ipc 共享内存 shared memmory
来源:互联网 发布:gfa交易算法gfajiaoyi 编辑:程序博客网 时间:2024/05/20 03:08
下面两篇博客对ipc shares memory 讲述的比较清晰
1.http://blog.chinaunix.net/uid-26833883-id-3230564.html
2.http://blog.csdn.net/ljianhui/article/details/10253345
共享内存(shared memory)是最简单的Linux进程间通信方式之一。使用共享内存,不同进程可以对同一块内存进行读写。由于所有进程对共享内存的访问就和访问自己的内存空间一样,而不需要进行额外系统调用或内核操作,同时还避免了多余的内存拷贝,所以,这种方式是效率最高、速度最快的进程间通信方式。
这种最大限度的自由也给共享内存带来了缺点:内核并不提供任何对共享内存访问的同步机制,比如同时对共享内存的相同地址进行写操作,则后写的数据会覆盖之前的数据。所以,使用共享内存一般还需要使用其他IPC机制(如信号量)进行读写同步与互斥。
基本原理
了解Linux内存管理机制,就很容易知道共享内存的原理了。大家知道,内核对内存的管理是以页(page)为单位的,Linux下一般一个page大小是4k。而程序本身的虚拟地址空间是线性的,所以内核管理了进程从虚拟地址空间到起对应的页的映射。创建共享内存空间后,内核将不同进程虚拟地址的映射到同一个页面:所以在不同进程中,对共享内存所在的内存地址的访问最终都被映射到同一页面。下图演示了共享内存的工作机制:
#include <sys/shm.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <semaphore.h>#include <fcntl.h>#include <sys/stat.h>#define BUFF_SIZE 1024int father_do_work(int shmid){ char *buf; void *shmaddr; sem_t *prsem; sem_t *pwsem; //有名信号量 if((prsem = sem_open("rsem",O_CREAT,0666,0)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } //有名信号量 if((pwsem = sem_open("wsem",O_CREAT,0666,1)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } //映射共享内存 if((shmaddr = shmat(shmid,NULL,0)) == (void *)-1) { perror("Fail to shmat"); exit(EXIT_FAILURE); } buf = (char *)shmaddr; while(1) { if(sem_wait(pwsem) < 0) { perror("Fail to sem wait"); break; } printf(">"); fgets(buf,BUFF_SIZE,stdin); buf[strlen(buf) - 1] = '\0'; if(sem_post(prsem) < 0) { perror("Fail to sem post"); break; } if(strncmp(buf,"quit",4) == 0) { if(shmdt(shmaddr) < 0) { perror("Fail to shmaddr"); exit(EXIT_FAILURE); } break; } usleep(500); } return 0;}int child_do_work(int shmid){ char *buf; void *shmaddr; sem_t *prsem; sem_t *pwsem; // if((prsem = sem_open("rsem",O_CREAT,0666,0)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } if((pwsem = sem_open("wsem",O_CREAT,0666,1)) == SEM_FAILED) { perror("Fail to sem open"); return -1; } //映射共享内存 if((shmaddr = shmat(shmid,NULL,0)) == (void *)-1) { perror("Fail to shmat"); exit(EXIT_FAILURE); } buf = (char *)shmaddr; while(1) { if(sem_wait(prsem) < 0) { perror("Fail to prsem"); break; } printf("read buf : %s.\n",buf); if(sem_post(pwsem) < 0) { perror("Fail to pwsem"); break; } if(strncmp(buf,"quit",4) == 0) { if(shmdt(shmaddr) < 0) { perror("Fail to shmaddr"); exit(EXIT_FAILURE); } break; } } return 0;}int main(){ int shmid; int pid; void *shmaddr; //创建共享内存 if((shmid = shmget((key_t)16,BUFF_SIZE,0666 | IPC_CREAT)) < 0) { perror("Fail to shmget"); exit(EXIT_FAILURE); } if((pid = fork()) < 0) { perror("Fail to fork"); exit(EXIT_FAILURE); }else if(pid == 0){ child_do_work(shmid); }else{ father_do_work(shmid); wait(NULL); if(shmctl(shmid,IPC_RMID,NULL) < 0) { perror("Fail to shmctl"); exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS);}
同时linux shell通过命令ipcs ipcrm分别对进程通信进行创建删除显示信息等操作
0 0
- ipc 共享内存 shared memmory
- 内存共享(Shared Memory)
- 共享内存: Shared Memory
- 多线程进程间通讯共享内存(Shared Memory with IPC with threads)
- 深入理解Linux进程间通信(IPC)-- 共享内存shared memory mmap
- IPC 共享内存
- IPC-shm 共享内存
- 共享内存IPC
- IPC之共享内存
- IPC-共享内存
- QT-IPC-内存共享
- IPC之共享内存
- IPC--共享内存
- IPC之共享内存
- IPC共享内存 shm
- IPC-共享内存
- IPC之共享内存
- IPC共享内存
- 机器学习相关——文本分类综述
- Qt学习笔记
- DM8168 开机自动运行程序
- 2014年11月1日-11月14日,共21小时,剩4/411小时
- Hdu 1133 Buy the Ticket[卡特兰数小变形]
- ipc 共享内存 shared memmory
- Red Hat 6.5修改yum源
- Verilog_例程笔记_流水灯&按键消抖
- 【Cocos2d-x】Cocos2d-x3.x创建项目
- [LeetCode] Balanced Binary Tree
- 基于I2C的FT5306触摸屏驱动程序执行流程
- LeetCode 136 3Sum Closest
- 使用ContactsContract APIhttp://www.cnblogs.com/carbs/archive/2012/07/16/2593295.html
- C语言的Static Inline函数