目录
1.命名管道
2.共享内存
3.共享内存和管道的生命周期
4.共享内存的优缺点
1.命名管道
命名管道和匿名管道的最大差别是:命名管道是创建在磁盘里的一个有名字的文件。这个文件不存实际的数据。但是不同进程可以通过文件路径找到相同的struct file(缓冲区)访问到这个文件,实现进程通信,进程通信的过程中发送和接收的数据不会被刷新到磁盘。匿名管道是创建在缓冲区的文件。
先了解一下mkfifo接口,pathname是管道的路径,mode是权限。
来用命名管道实现一个简单的进程通信
代码实现就不上了,看看效果。
这里我们明显就可以看出两个进程之间的通信。
2.共享内存
共享内存实际上就是在物理内存上申请了一块空间。不同的进程通过页表共同挂接到这块空间,从而实现通信。
这里我们需要了解一些接口:
pathname是要保证存在的一个路径,proj_id是权限。
作用是依据一个特殊的算法创建一个唯一的key值
最后返回这个key值
key就是上面的key,size表示共享内存的大小。建议设置为4096的倍数,你搞个4097操作系统会开4096*2字节,因为操作系统一会开4kb。shmflg的常用取值有IPC_CERATE 和 IPC_EXCL
前者表示不存在会创建这个共享内存,后者表示若是这个key值已经创建过共享内存了,我们就出错返回。而使用IPC_CREATE | IPC_EXCL |0666就可以创建出一个全新的共享内存且权限为666了。
最后返回一个类似文件描述符fd的数shmid。
shmid是上面shmget的返回值。用来让进程找到对应的共享内存,shmaddr和shmflg默认给nullptr和0,交于系统来处理挂接。这样我们就可以创建好进程与共享内存的挂接关系。
最后返回一个指针。
用上面的指针来解开进程与共享内存的挂接关系。
最后,shmctl用来销毁这个共享内存,shmid就是创建共享内存是的返回值。cmd一般给IPC_RMID表示就算还有进程挂在共享内存上,我也一样删除。最后的buf默认给nullptr。
实际上,挨着上面的接口走一遍就成功建立起一个进程与共享内存的连接。并最后删除了连接状态并删除了共享内存。
3.共享内存和管道的生命周期
管道的生命周期随进程,本质是内核中的缓冲区,命名管道文件只是标识,用于让多个进程找到同一块缓冲区,删除后,之前已经打开管道的进程依然可以通信。
共享内存生命周期随内核,只要不删除,就一直存在于内核中。不过它还有一种特殊的退出方式,只要本来所有与它连接的进程全部退出,共享内存同样会被销毁。
4.共享内存的优缺点
共享内存相对于管道而言,它的优点是进程间通信快,毕竟管道必须通过内核缓冲区才能将进程连接到指定的管道文件。而对于共享内存来说,它是直接将进程通过页表与物理内存相连接速度更快。缺点也很明显,太复杂,搞了这么一大套系统接口,linux下一般都是各个文件直接收系统管制。说白了就是System v的方式搞特例,我们不太喜欢。