共享内存是一种进程间的通信方式。
shmget(); 创建共享内存,返回标识符
shmat(); 把共享内存映射到进程的地址空间中
shdt(); 断开与共享内存的连接,非删除
shmctl(); 共享内存管理(删除,或改变状态)
Linux操作共享内存相关命令
ipcs 查看消息队列,共享内存和信号量
ipcrm -m 32769 删除标识为32769的共享内存
程序例子,父子间进程通信:
#include <stdio.h> #include <sys/types.h> #include <sys/shm.h> #include <sys/ipc.h> #include <string.h> #define SIZE 1024 int main() { int shmid; pid_t pid; char *shmaddr; int flag; struct shmid_ds buf; shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT|0600); if(shmid < 0) { perror("get shm ipc_id error"); return -1; } if((pid = fork()) < 0) { perror("get fork error"); return -1; } else if(pid == 0) { /* child */ shmaddr = (char *)shmat(shmid, NULL, 0); if((int)shmaddr == -1) { perror("shmat error"); return -1; } strcpy(shmaddr, "Hi,I am child process!\n"); shmdt(shmaddr); return 0; } else { /* parent */ sleep(3); flag = shmctl(shmid, IPC_STAT, &buf); if(flag == -1) { perror("shmctl error"); return -1; } printf("shm_segsz=%d bytes\n", buf.shm_segsz); printf("parent pid=%d,shm_cpid=%d \n", getpid(), buf.shm_cpid); printf("child pid=%d,shm_lpid=%d\n", pid, buf.shm_lpid); shmaddr = (char *)shmat(shmid, NULL, 0); if((int)shmaddr == -1) { perror("parent:shmat error"); return -1; } printf("shmaddr in %s\n", shmaddr); shmdt(shmaddr); shmctl(shmid, IPC_RMID, NULL); } return 0; }
编译
gcc shm.c -o shm
输出结果
shm_segsz=1024 bytes parent pid=6163,shm_cpid=6163 child pid=6164,shm_lpid=6164 shmaddr in Hi,I am child process!
程序例子,进程之间使用共享内存通信
shmwrite.c
#include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <string.h> typedef struct { char name[8]; int age; }people; int main() { int shmid; key_t key; char temp[8]; char pathname[30]; people *p_map; int i; strcpy(pathname, "/tmp"); key = ftok(pathname, 0x03); if(key == -1) { perror("ftok error\n"); return -1; } printf("key=%d\n", key); shmid = shmget(key, 4096,IPC_CREAT|IPC_EXCL|0600); if(shmid == -1) { perror("shmget error\n"); return -1; } printf("shmid=%d\n",shmid); p_map = (people *)shmat(shmid, NULL, 0); if((int)p_map == -1) { perror("shmat error\n"); return -1; } 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=i; } if(shmdt(p_map) == -1) { perror("shmdt error\n"); return -1; } return 0; }
shmread.c
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char name[8]; int age; }people; int main(int argc, char *argv[]) { int shmid; people *p_map; key_t key; char pathname[30]; int i = 0; strcpy(pathname, "/tmp"); key = ftok(pathname, 0x03); if(key == -1) { perror("ftok error\n"); return -1; } printf("key=%d\n", key); shmid = shmget(key, 0, 0); if(shmid == -1) { perror("shmread:shmget error\n"); return -1; } printf("shmid=%d\n",shmid); p_map = (people*)shmat(shmid, NULL, 0); for(i=0;i<3;i++) { printf("name:%s\n", (*(p_map+i)).name); printf("age:%d\n", (*(p_map+i)).age); } if(shmdt(p_map) == -1) { perror("shmdt error\n"); return -1; } return 0; }
编译
gcc shmread.c -o shmread gcc shmwrite.c -o shmwrite
shmwrite执行结果
key=50397185 shmid=262144
shmread执行结果
key=50397185 shmid=262144 Segmentation fault (core dumped)
结果很奇怪, 不知道为什么
参考资料:
https://www.cnblogs.com/ch122633/p/8068152.html
https://blog.youkuaiyun.com/wteruiycbqqvwt/article/details/90484317