int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
创建共享内存段和创建信号量非常相似,都是值得一个key,然后返回一个id。
int id = shmget((key_t)key, size, 0666|IPC_CREAT|IPC_EXCL)
如果返回的id是-1,说明创建失败。此时需要判断errno,如果errno等于EEXIST,说明共享内存段已经存在。
if((id = shmget((key_t)key, size, 0)) < 0)
printf("get exists shared memory: %d\n", id);
EINVAL 多种原因,比如指定的size不符合SHMMIN和SHMMAX
ENOENT 没有找到指定key对应的共享内存段,同时又没有指定IPC_CREAT
ENOSPC 共享内存的ID用完了(SHMMNI), 或者超过共享内存的系统限制(SHMALL)
EPERM 指定了SHM_HUGETLB,但是没有权限(did not have the CAP_IPC_LOCK capability)
得到共享内存端的id之后,就可以attach。attach就是把共享内存的地址映射到自己的地址空间里。
void* p = shmat(id, NULL, 0666);
第二个参数是希望映射到的地址,如果不指定,就会自动映射一个地址。
attach得到的地址传给shmdt就可以完成detach
int shmdt(const void *shmaddr);
shmctl(id,IPC_RMID, NULL);
int initshm(int key, int size, void** p)
if((id = shmget((key_t)key, size, 0666|IPC_CREAT|IPC_EXCL)) < 0)
if((id = shmget((key_t)key, size, 0)) < 0)
printf("get exists shared memory: %d\n", id);
printf("create shared memory: %d\n", id);
if((*p = shmat(id, NULL, 0666)) == NULL)
return shmctl(id,IPC_RMID, NULL);
int key = ftok("a.c", 1);
if((id = initshm(key, BUFSIZ, (void**)&p)) < 0)
printf("shmget(): %s\b", strerror(errno));
if(strcmp(cmd, "p") == 0)
printf("share memory: %s\n", p);
else if(strcmp(cmd, "w") == 0)
else if(strcmp(cmd, "q") == 0)
printf("shared memory %d deleted.\n", id);
printf("shmget(): %s\b", strerror(errno));
create shared memory: 393221
get exists shared memory: 393221
按p回车,输出shell 1保存到共享内存里的内容
然后shell 1 和 shell 2 可以交替修改和打印共享内存段。
[root@server2 ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 gdm 600 393216 2 dest
0x00000000 32769 gdm 600 393216 2 dest
0x00000000 65538 gdm 600 393216 2 dest
0x00000000 98307 gdm 600 393216 2 dest
0x01026a7d 393221 root 666 8192 2 [root@server2 ~]# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 gdm 600 393216 2 dest
0x00000000 32769 gdm 600 393216 2 dest
0x00000000 65538 gdm 600 393216 2 dest
0x00000000 98307 gdm 600 393216 2 dest
0x01026a7d 393221 root 666 8192 0 来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2075998/,如需转载,请注明出处,否则将追究法律责任。