基本概念
共享内存区域是被多个进程共享的一部分物理内存,如果多个进程都把该内存区域映射到自己的虚拟地址空间,则这些进程就都可以直接访问该内存区域,从而可以通过该区域进行通信。共享内存是进程间共享数据的一种更快的方法,一旦这样的内存映射到共享它的进程地址空间,这些进程间数据传递不在涉及到内核,换句话说是进程不在通过执行进入到内核的系统调用来传递彼此的数据。一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容,这块共享虚拟内存的页面,出现在每一个共享该页面进程的页表中,但是它不需要在所有进程中的虚拟内存中都有相同的虚拟地址
共享内存与其他IPC 进行比较
优点:
- 共享内存是进程通信方式中最快速的方式之一,它的快速体现在,为数据共享而进行的复制非常少。这里举例来说,使用消息队列时,一个进程向消息队列写入消息时,这里有一次数据的复制,从用户空间到内核空间,这无疑是耗费时间与资源的,然而共享内存的存在则无需这两次复制,进程是从它们各自的地址空间直接访问共享的内存区段的
缺点:
- 还是拿消息队列来比,消息队列已经实现了对自身读写的保护,然而共享内存要我们开发者自己来实现,这无疑增加了开发的难度
共享内存有关函数
获取key值
- key_t ftok(const char *pathname, int proj_id)//第一个参数和第二个参数自己随便给(第一个参数必须是以存在且可以访问的文件名),只要不和系统重复就行
创建或打开共享内存
- int shmget(key_t key, size_t size, int shmflg);//第二个参数为创建的共享内存大小,第三个参数为IPC_CREAT| 0644创建共享内存,如为0表示打开已创建好的共享内存
- 返回值:成功为0,失败-1
将共享内存映射到自己的虚拟地址空间
- void * shmat(int shmid, const void *shmaddr , int shmflg);//第一个参数表示共享内存段的标识符,第二个参数设置为NULL,让操作系统来写,第三个参数通常设置为0
- 返回值:为映射到的虚拟地址空间的起始地址
- int shndt(const void * shmaddr);//参数为上个函数的返回值
控制共享内存
- int shmctl(int shmid, int cmd,struct shmid_ds *buf);//第二个参数为IPC_RMID,第三个参数为0;表示删除(释放)该共享内存段
命令行查看删除共享内存段
- 查看 ipcs -m
- 删除 ipcrm -M shmid
子进程向共享内存写消息,父进程读
运行结果如下: