如何等待/阻塞直到信号量值在 Windows 中达到 0

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1175868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:51:30  来源:igfitidea点击:

How to wait/block until a semaphore value reaches 0 in windows

windowssemaphore

提问by MSN

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?

在 unix 上使用 semop() 函数,可以提供 sem_op =0 的 sembuf 结构。本质上,这意味着调用进程将等待/阻塞,直到信号量的值变为零。在 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/

关于 unix semop 系统调用的文档可以在这里找到:http: //codeidol.com/unix/advanced-programming-in-unix/Interprocess-Communication/-15.8.-Semaphores/

回答by MSN

Assuming you have one writer thread, just have the writer thread gobble up the semaphore. I.e., grab the semaphore via WaitForSingleObjectfor however many times you initialized the semaphore count to.

假设您有一个编写器线程,只需让编写器线程吞噬信号量即可。即,通过WaitForSingleObject多次初始化信号量计数来获取信号量。

回答by Anton Tykhyy

A Windows semaphorecounts downfrom the maximum value (the maximum number of readers allowed) to zero. WaitXxxfunctions wait for a non-zero semaphore value and decrementit, ReleaseSemaphoreincrementsthe 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.

一个视窗信号量计数下来从最大值(允许的读者数量上限)至零。WaitXxx函数等待非零信号量值并将其递减增加信号量(允许其他线程等待信号量解除阻塞)。不可能以不同的方式等待 Windows 信号量,因此在您的情况下,Windows 信号量可能是同步原语的错误选择。在 Vista/2008 上,您可以使用细长的读写锁;如果您需要支持较早版本的 Windows,则必须自行开发。ReleaseSemaphore

回答by pilcrow

The specific use case I'm trying to implement is to wait until the number of readers reaches zero before letting a writer write.

我试图实现的具体用例是等待读者数量达到零,然后再让作者写。

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.

如果是这样,您可以使用手动重置事件对象实现等效于 SysV“等待零”的行为,发出最后一个读取器的完成信号。维护您自己的(同步)“活动读者”计数,随着读者完成而递减,然后SetEvent()在该计数为零时向耐心等待的作者发出信号。

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.

如果您不能保证读者会表现得很好,那么即使使用 SysV sem,您也将面临一场不愉快的竞赛。

回答by Tim Sylvester

I've never seen any function similar to that in the Win32 API.

我从未见过与 Win32 API 中的函数类似的任何函数。

I think the way to do this is to call WaitForSingleObjector similar and get a WAIT_OBJECT_0the 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.

我认为这样做的方法是调用WaitForSingleObject或类似的方法并获得WAIT_OBJECT_0与创建信号量时指定的最大计数相同的次数。然后,您将持有所有可用的“插槽”,其他任何等待信号量的人都会被阻塞。