1、概念共享内存Shared Memory就是允许多个进程访问同一个内存空间是在多个进程之间共享和传递数据最高效的方式。操作系统将不同进程之间共享内存安排为同一段物理内存进程可以将共享内存连接到它们自己的地址空间中如果某个进程修改了共享内存中的数据其它的进程读到的数据也将会改变。2、创建共享内存1.int shmget(key_t key, size_t size, int shmflg); //用来获取或创建共享内存 参数 keyIPC_PRIVATE 或 ftok的返回值 size共享内存区大小 shmflg同open函数的权限位也可以用8进制表示法 返回值 成功共享内存段标识符‐‐‐ID‐‐‐文件描述符 出错‐1#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h int main() { int shmid; shmid shmget(IPC_PRIVATE,128,0755); if(shmid-1) { printf(create share memory failed\n); return -1; } printf(create share memory succeed shmid %d\n,shmid); system(ipcs -m); return 0; }删除共享内存的指令ipcrm -m shmid3、单个进程读和写void *shmat(int shm_id, const void *shm_addr, int shmflg); //把共享内存连接映射到当前进程的地址空间 参数 shm_id:ID号 shm_addr:映射到的地址NULL为系统自动完成的映射 shmflg SHM_RDONLY共享内存只读 默认是0表示共享内存可读写 返回值 成功映射后的地址 失败NULL#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h int main() { int shmid; char *p; shmid shmget(IPC_PRIVATE,128,0755); if(shmid-1) { printf(create share memory failed\n); return -1; } printf(create share memory succeed shmid %d\n,shmid); system(ipcs -m); p (char *)shmat(shmid,NULL,0); if(p NULL) { printf(shmat funtion failed\n); return -2; } //write to share memory fgets(p,128,stdin); //read from share memory printf(share memory data is %s\n,p); return 0; }管道和消息队列都是一次性读取的读一次之后内容就被删除了而共享内存不一样不论都多少次那条消息都在。IPC 方式读完是否消失数据模型适用场景管道 / FIFO✅ 读走就没字节流单向临时传输消息队列✅ 读走就没独立报文 (带 type)收发消息、一对一共享内存❌ 读一万次都在内存区块大数据、高频交互3、删除地址映射int shmdt(const void *shmaddr); //将进程里的地址映射删除 参数 shmid要操作的共享内存标识符 返回值 成功0 出错‐1#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h #includestring.h int main() { int shmid; char *p; shmid shmget(IPC_PRIVATE,128,0755); if(shmid-1) { printf(create share memory failed\n); return -1; } printf(create share memory succeed shmid %d\n,shmid); system(ipcs -m); p (char *)shmat(shmid,NULL,0); if(p NULL) { printf(shmat funtion failed\n); return -2; } //write to share memory fgets(p,128,stdin); //read from share memory printf(share memory data is %s\n,p); shmdt(p); memcp(p,hello,5); return 0; }地址映射被删除了所以最后写的hello无处可写4、删除共享内存对象int shmctl(int shm_id, int command, struct shmid_ds *buf); //删除共享内存对象 参数 shmid要操作的共享内存标识符 cmd IPC_STAT (获取对象属性)‐‐‐ 实现了命令ipcs ‐m IPC_SET (设置对象属性) IPC_RMID (删除对象) ‐‐‐实现了命令ipcrm ‐m buf 指定IPC_STAT/IPC_SET时用以保存/设置属性 返回值 成功0 出错‐1#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h int main() { int shmid; char *p; shmid shmget(IPC_PRIVATE,128,0755); if(shmid-1) { printf(create share memory failed\n); return -1; } printf(create share memory succeed shmid %d\n,shmid); system(ipcs -m); p (char *)shmat(shmid,NULL,0); if(p NULL) { printf(shmat funtion failed\n); return -2; } //write to share memory fgets(p,128,stdin); //read from share memory printf(share memory data is %s\n,p); shmdt(p); shctl(shmid,IPC_RMID,NULL); system(ipcs -m); return 0; }5、共享内存实现ipcrm#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h #includestring.h int main(int argc,char *argv[]) { int shmid; if(argc3) { printf(input error\n); return -1; } if(strcmp(argv[1],-m) 0) { printf(delete share memory\n); } else { return -2; } shmid atoi(argv[2]); printf(delete share memory id:%d\n,shmid); shmctl(shmid,IPC_RMID,NULL); system(ipcs -m); return 0; }atoi是将输入的字符串转成数字因为shmid是整型而输入的是字符串6、共享内存进程间通信写端#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h #includestring.h #includeunistd.h int main() { int shmid; char *p; int pid; int key; key ftok(a.c,1); if(key 0) { printf(ftok failed\n); return -2; } printf(ftok succeed key:%x\n,key); shmid shmget(key,128,IPC_CREAT|0777); if(shmid0) { printf(create share memory failed\n); return -1; } printf(create share memory succeed shmid %d\n,shmid); p (char *)shmat(shmid,NULL,0); if(p NULL) { printf(shmat funtion failed\n); return -3; } printf(please input to share memory:\n); //write to share memory fgets(p,128,stdin); sleep(3); shmdt(p); shmctl(shmid,IPC_RMID,0); return 0; }读端#includestdio.h #include sys/ipc.h #include sys/shm.h #includestdlib.h #includestring.h int main() { int shmid; char *p; int pid; int key; key ftok(a.c,1); if(key 0) { printf(ftok failed\n); return -2; } printf(ftok succeed key:%x\n,key); shmid shmget(key,128,0); if(shmid0) { printf(create share memory failed\n); return -1; } printf(create share memory succeed shmid %d\n,shmid); p (char *)shmat(shmid,NULL,0); if(p NULL) { printf(shmat funtion failed\n); return -3; } printf(share memory data:%s\n,p); shmdt(p); return 0; }注意我在写端延迟了3秒再删除地址映射也就是说写端输入完之后3秒之内要在另一个终端执行读端否则将什么也读不到。