当前位置: 技术问答>linux和unix
linux下多进程访问共享内存队列同步的问题
来源: 互联网 发布时间:2017-01-13
本文导语: 1.我要做的是多进程间同步一个共享内存队列,控制同步用的是信号量。 2.队列封装到一个类里。只对外提供三个接口:init push pop。同步的过程对外完全透明。 3.为了保证 信号量的初始值不会在多进程并发执行的...
1.我要做的是多进程间同步一个共享内存队列,控制同步用的是信号量。
2.队列封装到一个类里。只对外提供三个接口:init push pop。同步的过程对外完全透明。
3.为了保证 信号量的初始值不会在多进程并发执行的情况下被弄乱,并且必须保证其在多个进程间只被初始化一次。并且初始化完之后,才进行semop 操作。
4.为了保证第三点,我想用一个互斥量。
5.为了这个互斥量能够在多进程间共享,在另外一块共享内存里动态分配, 分配之后要设置PTHREAD_PROCESS_SHARED属性。
现在的问题是:设置PTHREAD_PROCESS_SHARED属性 的操作在多进程间是并发执行的,怎么保证这个互斥量只被初始化一次?
或者有没其他更好的方法保证信号量的初始值在多个进程间只被初始化一次?
2.队列封装到一个类里。只对外提供三个接口:init push pop。同步的过程对外完全透明。
3.为了保证 信号量的初始值不会在多进程并发执行的情况下被弄乱,并且必须保证其在多个进程间只被初始化一次。并且初始化完之后,才进行semop 操作。
4.为了保证第三点,我想用一个互斥量。
5.为了这个互斥量能够在多进程间共享,在另外一块共享内存里动态分配, 分配之后要设置PTHREAD_PROCESS_SHARED属性。
现在的问题是:设置PTHREAD_PROCESS_SHARED属性 的操作在多进程间是并发执行的,怎么保证这个互斥量只被初始化一次?
或者有没其他更好的方法保证信号量的初始值在多个进程间只被初始化一次?
|
直接看网络编程卷2的sem章节,semget IPC_CREAT|IPC_EXCL|MODE创建,如果失败则说明信号量已创建,那么调用semget直接打开信号量,然后调用semctl用IPC_STAT获取ds,看ds.sem_otime是否为0,该函数只有在sem_op调用成功之后才设置为非0,所以该进程轮询等待ds.sem_otime!=0就可以开始使用了。
也就是谁创建谁初始化,是否初始化完成是由创建者semctl初始化之后semop调用一次来指示的。
其实类似的办法很多,你也可以创建信号量时候,给MODE加个没有用的权限,比如S_IXOTH, 就是给其他用户执行权限。 那么其他进程发现信号量已存在,于是直接打开,并且semctl IPC_STAT去检查ds.perm里的mode是否有S_IXOTH,如果有就继续等待,直到创建进程semctl SET取消这个S_IXOTH为止。
其实POSXI的各种IPC都可以借助我说的这种权限位的方法实现。
|
还有,楼主的设计其实我不太赞同,你完全可以互斥量+条件变量+元素个数+共享内存+循环队列。
根本不需要system v的信号量。
元素个数为0,则get阻塞在cond_wait。
元素个数满,则put阻塞在cond_wait上。
get的时候,如果元素个数满,则cond_signal。
put的时候,如果元素个数0,则cond_signal。
再牛逼一点,加一个等待读计数,等待写计数。
如果put发现元素个数满,那么等待写+1.
如果get发现元素个数0,则等待读+1.
借助计数,可以优化这个队列为读优先或者写优先。
甚至,这样做,我们可以提供非阻塞get/put接口,这是什么档次。