标签:
与共享内存相关的操作主要包括共享内存的初始化, 共享内存的释放, 共享内存的锁的相关操作, 在这里操作共享内存的环境是:
1 多个进程没有亲缘关系, 也没有server/client关系, 是多个不相关进程并发操作共享内存
2 共享内存一开始不存在, 由第一个访问他的进程创建
3 当共享内存退出时, 由最后一个离开的进程释放共享内存, 并清除信号量
在这个问题之中, 主要有两个比较大的问题:
新建共享内存的数据都可以用信号量来控制, 但是信号量的初始化由谁来控制呢?
信号量中创建(semget)和赋值(sem)分开是造成这一问题的根源, 如果不对信号量初始化进行控制, 严重的时候会出现以下情景:
当A进程判断信号量没有初始化时, 准备去初始化, 而同时进程B也发现信号量没有初始化, 要去初始化, 并且在初始化后上锁, 此时进程A再次初始化信号量, 就会造成错误.
我的解决方法:
解决这个问题, 我们主要需要一个原子性的操作, 来帮助创建信号量.link函数正好可以满足我们的这个要求, link的操作是原子性的.
当多个进程判断需要初始化共享内存时,我们让这些进程每个单独创建一个共享内存的副本, 然后link到真正的共享内存上, 谁先link到真正的共享内存上, 就算是这个进程创建的.
在使用mmap做共享内存时, 打开关闭共享文件主要有两种方式, 一种是使用open – close, 另一种是使用 shm_open – shm_unlink, 这两种方式的优缺点如下:
Open-close:
优点: 当一个使用共享内存的进程退出时, 关闭共享文件描述符, 不会删除文件, 下一个使用共享内存的文件依旧可以进入
缺点: 需要自己手动管理文件的删除, 最后一个进程要删除文件时, 依然有进程可能打开并映射该共享内存文件.
Shm_open-shm_unlink:
优点: 对于共享文件的删除可以交给内核来做, 内核会在最后一个进程退出时, 删除共享文件,使用共享文件的进程数一旦减少就不会增加了,所以比较容易确定什么时候删除信号量.
缺点: shm_unlink的工作方式类似unlink, 一旦一个进程退出后, 这个共享文件就无法访问了, 其他进程就无法再使用该共享内存, 而需要创建新的共享内存.
进程A,B,C三个进程使用共享内存
进程C退出
为了避免在删除共享文件时的复杂性,我现在使用的shm_open-shm_unlink的方式
原来的共享内存由于unlink过,由内核维护,但已无法被新的进程访问,进程D,E再进入需要重新创建共享内存
初始化:
打开共享文件:
关闭共享文件
标签:
原文地址:http://www.cnblogs.com/zhangfann/p/4655591.html