如何在 Windows 中等待/阻塞直到信号量值达到 0
在 unix 上使用 semop() 函数,可以提供 sem_op =0 的 sembuf 结构。 本质上,这意味着调用进程将等待/阻塞,直到信号量的值变为零。 在 Windows 中是否有等效的方法来实现此目的?
我试图实现的具体用例是等到读者数量达到零后再让作家写作。 (是的,这是使用信号量的一种有点非正统的方式;这是因为读取器的数量没有限制,因此没有信号量通常用来管理的一组受限资源)
有关 unix semop 系统调用的文档可以是在这里找到: http://codeidol.com/unix /advanced-programming-in-unix/进程间通信/-15.8.-信号量/
Using the semop() function on unix, it's possible to provide a sembuf struct with sem_op =0. Essentially this means that the calling process will wait/block until the semaphore's value becomes zero. Is there an equivalent way to achieve this in windows?
The specific use case I'm trying to implement is to wait until the number of readers reaches zero before letting a writer write. (yes, this is a somewhat unorthodox way to use semaphores; it's because there is no limit to the number of readers and so there's no set of constrained resources which is what semaphores are typically used to manage)
Documentation on unix semop system call can be found here:
http://codeidol.com/unix/advanced-programming-in-unix/Interprocess-Communication/-15.8.-Semaphores/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
假设您有一个写入器线程,只需让写入器线程吞噬信号量即可。 即,无论您初始化信号量计数多少次,都可以通过
WaitForSingleObject
获取信号量。Assuming you have one writer thread, just have the writer thread gobble up the semaphore. I.e., grab the semaphore via
WaitForSingleObject
for however many times you initialized the semaphore count to.Windows 信号量从最大值(允许的最大读卡器数量)为零。
WaitXxx
函数等待非零信号量值并递减它,ReleaseSemaphore
增加信号量(允许等待信号量的其他线程解除阻塞)。 不可能以不同的方式等待 Windows 信号量,因此在您的情况下,Windows 信号量可能是同步原语的错误选择。 在 Vista/2008 上,您可以使用 slim 读写锁; 如果您需要支持早期版本的 Windows,则必须自行推出。A Windows semaphore counts down from the maximum value (the maximum number of readers allowed) to zero.
WaitXxx
functions wait for a non-zero semaphore value and decrement it,ReleaseSemaphore
increments the semaphore (allowing other threads waiting on the semaphore to unblock). It is not possible to wait on a Windows semaphore in a different way, so a Windows semaphore is probably the wrong choice of synchronization primitive in your case. On Vista/2008 you could use slim read-write locks; if you need to support earlier versions of Windows you'll have to roll your own.我从未见过任何与 Win32 API 中类似的函数。
我认为执行此操作的方法是调用
WaitForSingleObject
或类似方法,并获取WAIT_OBJECT_0
,次数与创建信号量时指定的最大计数相同。 然后,您将保留所有可用的“槽”,而等待信号量的其他人将被阻塞。I've never seen any function similar to that in the Win32 API.
I think the way to do this is to call
WaitForSingleObject
or similar and get aWAIT_OBJECT_0
the same number of times as the maximum count specified when the semaphore was created. You will then hold all the available "slots" and anyone else waiting on the semaphore will block.你能保证读者计数将保持为零,直到作者完成所有工作吗?
如果是这样,您可以使用 手动重置事件对象,表示最后一个读取器已完成。 维护您自己的(同步)“活动读者”计数,随着读者完成而递减,然后在该计数为零时通过
SetEvent()
向耐心等待的编写者发出信号。如果您不能保证读者表现良好,那么即使使用 SysV sem,您也会遇到一场不愉快的竞争。
Can you guarantee that the reader count will remain at zero until the writer is all done?
If so, you can implement the equivalent of SysV "wait-for-zero" behavior with a manual-reset event object, signaling the completion of the last reader. Maintain your own (synchronized) count of "active readers", decrementing as readers finish, and then signal the patiently waiting writer via
SetEvent()
when that count is zero.If you can't guarantee that the readers will be well behaved, well, then you've got an unhappy race to deal with even with SysV sems.