共享内存的进程同步问题, Windows 的 API 真难用!

www_adintr_com 2009-07-14 10:20:08
问题很简单,有多个进程(数量会动态变化)对一块共享内存进行操作,要实现的读写规则如下:
1. 一个进程在写入时其它进程不能读也不能写。
2. 多个进程可以同时读。
3. 只要还有一个进程在读,就不能进行写入。
当读写操作不能进行时应该立即返回不能读写的信息,而不能一直阻塞到可读写的状态。

对写入的判断还好,用 Event 就可以实现了。
读取由于可以多个同时读,所以需要一个计数,于是就用 Semaphore,可是 Windows API 对这个对象提供的操作太弱智了,感觉完全没办法满足要求,请教各位如何设计才能满足上面的同步规则?
...全文
1481 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
www_adintr_com 2009-07-16
  • 打赏
  • 举报
回复
我也想用 Semaphore, 自己维护变量总觉得不牢靠,万一在这个变量的某个操作中进程突然崩溃了或者怎么样了,这个变量就会一直处于异常状态,导致后续操作出现错误。而系统的内核操作系统可以保证进程异常之类的这些资源也会正确释放。
但是 Semaphore 好难用,感觉完全就不是为这种用法设计的,首先它的构造 CreateSemaphore 就要一个最大数量,而我的数量是动态变化的。其次,它的激发状态恰好与我的需求相反,它是只要计数大于 0 就处于激发状态,而 ReleaseSemaphore 是增加计数, WainForSingleObject 里面减少计数,这样我得以完全相反的方法来使用 ReleaseSemaphore -> 读操作 -> WaitForSingleObject!!
microyzy 2009-07-16
  • 打赏
  • 举报
回复
因为你现在的想法是和自己维护变量一样的想法,不妨转换一下想法,来适应系统的函数。
cnzdgs 2009-07-15
  • 打赏
  • 举报
回复
用一个long型共享变量,变量为0表示内存没有被访问,用InterlockedAdd对该变量进行操作。如果要读内存,先将改变量加1,然后判断如果返回值大于0,则可以继续操作,操作完后将变量加-1,如果返回值小于0,则不能操作,将变量加-1后执行其它操作;如果要写内存,先将变量加-65536,然后判断如果返回值等于-65536,则可以继续操作,操作完后将变量加65536,如果返回值不等于-65536,则不能操作,将变量加65536后执行其它操作。
副组长 2009-07-15
  • 打赏
  • 举报
回复
谁读谁设置Mutex,
谁写谁LOCK
读操作能读就读,写操作看Mutex。
w29468 2009-07-15
  • 打赏
  • 举报
回复
同意6楼,读的计数直接用原子变量就可以了
qq675927952 2009-07-15
  • 打赏
  • 举报
回复
up semaphore
microyzy 2009-07-15
  • 打赏
  • 举报
回复
Semaphore可以用吧,releasesemaphore的第三个参数会返回此前的信号值。
例如你每个进程无论读写都要wait(0)一下Semaphore,读完之后release。
而对写的进程,立即release,就知道当前有多少个进程在读数据,只要保证信号值大于等于线程数量即可。
没有unix下的方便就是了。
gg606 2009-07-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 microyzy 的回复:]
Semaphore可以用吧,releasesemaphore的第三个参数会返回此前的信号值。
例如你每个进程无论读写都要wait(0)一下Semaphore,读完之后release。
而对写的进程,立即release,就知道当前有多少个进程在读数据,只要保证信号值大于等于线程数量即可。
没有unix下的方便就是了。
[/Quote]

顶起!
虽然没有实际用过,但感觉Semaphore可以。
oyljerry 2009-07-14
  • 打赏
  • 举报
回复
读写可以用Mutex等互斥,而读你可以维护一个链表List等,写的时候看是否有读,读的时候看写的Mutex..
fengrx 2009-07-14
  • 打赏
  • 举报
回复
列表添加和删除操作时,请使用互斥保护。
fengrx 2009-07-14
  • 打赏
  • 举报
回复
一个思路:
对于读,存储为列表,开始读时增加,读取完成时删除,在写时判断列表是否为空。
  • 打赏
  • 举报
回复
可以使用读写指针进行操作
捕鲸叉 2009-07-14
  • 打赏
  • 举报
回复
用读写锁可以实现,windows Vista等新系统直接有API,XP等系统可以自己实现,实现的方法可以看下面的网页:
http://blog.chinaunix.net/u/18517/showart_1422763.html

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧