views:

1100

answers:

4

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/

A: 

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 a WAIT_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.

Tim Sylvester
A: 

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.

Anton Tykhyy
A: 

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.

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.

pilcrow
+1  A: 

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.

MSN