目的

学习shm相关API

read端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
typedef struct{
char name[8];
int age;
} people;
int main(int argc, char** argv)
{
int shm_id,i;
key_t key;
people *p_map;
char pathname[30] ;
strcpy(pathname,"/tmp") ;
// 参数fname是指定的文件名,这个文件必须是存在的而且可以访问的。id是子序号,它是一个8bit的整数。即范围是0~255
// key_t ftok(const char *pathname, int proj_id);
// 执行成功,则会返回key_t键值,否则返回-1
// ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。
// 该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
// proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255;
key = ftok(pathname,0x033);
if(key == -1)
{
perror("ftok error");
return -1;
}
printf("key=%d\n", key) ;
// 得到一个共享内存标识符或创建一个共享内存对象
// 会建立新共享内存对象,
// size_t 新建的共享内存大小,以字节为单位,只获取共享内存时指定为0
// shmflg 取共享内存标识符,若不存在则函数会报错 IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内存的标识符,IPC_CREAT|IPC_EXCL:如果内核中不存在键值 与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存则报错
// int shmget(key_t, size_t, int shmflg);
shm_id = shmget(key,0, 0);
if(shm_id == -1)
{
perror("shmget error");
return -1;
}
printf("shm_id=%d\n", shm_id) ;
// 把共享内存区对象映射到调用进程的地址空间
// 连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问
// shmid 共享内存标识符
// shmaddr 指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
// shmflg SHM_RDONLY:为只读模式,其他为读写模式.
// void *shmat(int shmid, const void *shmaddr, int shmflg)
// 成功:附加好的共享内存地址
// 出错:-1,错误原因存于error中
p_map = (people*)shmat(shm_id,NULL,0);
for(i = 0;i<3;i++)
{
printf( "name:%s\n",(*(p_map+i)).name );
printf( "age %d\n",(*(p_map+i)).age );
}
// 断开共享内存连接
// int shmdt(const void *shmaddr)
// shmaddr:连接的共享内存的起始地址
// 成功:0
// 出错:-1,错误原因存于error中
if(shmdt(p_map) == -1)
{
perror("detach error");
return -1;
}
return 0 ;
}

write端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
typedef struct{
char name[8];
int age;
} people;
int main(int argc, char** argv)
{
int shm_id,i;
key_t key;
char temp[8];
people *p_map;
char pathname[30] ;
strcpy(pathname,"/tmp") ;
key = ftok(pathname,0x033);
if(key==-1)
{
perror("ftok error");
return -1;
}
printf("key=%d\n",key) ;
shm_id=shmget(key,4096,IPC_CREAT|IPC_EXCL|0600);
if(shm_id==-1)
{
perror("shmget error");
return -1;
}
printf("shm_id=%d\n", shm_id) ;
p_map=(people*)shmat(shm_id,NULL,0);
memset(temp, 0x00, sizeof(temp)) ;
strcpy(temp,"test") ;
temp[4]='0';
for(i = 0;i<3;i++)
{
temp[4]+=1;
strncpy((p_map+i)->name,temp,5);
(p_map+i)->age=0+i;
}
shmdt(p_map) ;
return 0 ;
}

编译和运行

1
2
3
4
5
gcc shmwrite.c -o shmwrite
./shmwrite

gcc shmread.c -o shmread
./shmread