My program essentially consists of multiple bounded-buffer queues with one
consumer for each queue. There is a single producer for all queues. A queue
is guarded by a mutex and a pair of semaphores (one to represent the # of
unused buffers and one to represent the # of used buffers in the queue). So
the producer basically waits until there is a queue with unused buffer. Then
it produces a piece of data and puts it in that queue. So I plan to use
WaitForMultipleObjects() to wait on all the semaphores that represent # of
unused buffers. The problem is that if there are more than 1 semaphores that
get signalled in a single WaitForMultipleObjects() call, then
WaitForMultipleObjects() only tells you the index value of the semaphore
with the smallest index value of all the signalled semaphores. In general,
there is no information returned from WaitForMultipleObjects() that could
identify all the objects that have been signalled. You only know the one
with the smallest index. For semaphore objects, this seems to be a problem
because there is no other way to find out whether other semaphores have been
signalled unless you call WaitForMultipleObjects() on them again. But each
time you wait on a semaphore, you decrease its count. So semantically, this
is wrong.
Could anyone point out what's wrong here?
-Kim
>WaitForMultipleObjects() only tells you the index value of the semaphore
>with the smallest index value of all the signalled semaphores. In general,
>there is no information returned from WaitForMultipleObjects() that could
>identify all the objects that have been signalled. You only know the one
>with the smallest index. For semaphore objects, this seems to be a problem
>because there is no other way to find out whether other semaphores have been
>signalled unless you call WaitForMultipleObjects() on them again. But each
>time you wait on a semaphore, you decrease its count. So semantically, this
>is wrong.
>Could anyone point out what's wrong here?
The only semaphore whose count got decremented is the lowest indexed
one in the list of semaphores you passed in whose state was signaled
when your thread got awaken. Just because a whole bunch of them got
signaled doesn't mean they all decrement when you thread awakes
(unless you specified bWaitAll to true when you made the call to
WaitForMultipleObjects()).
If five of them got signaled, you will need to call
WaitForMultipleObjects() five times before the call blocks again
(assuming there are no more semaphores getting released in the mean
time).
(It's easier to express this in the case of a mutex: on return,
you have "gained ownership" of one mutex.)
dave
--
For email, please remove the 'w' from my address. Sorry.
Kim Liu <kl...@imedia.com> wrote in article
<6f9mpv$95u$1...@client3.news.psi.net>...
> I have a question on using WaitForMultipleObjects() to wait for multiple
> semaphores. I want the wait to return when any semaphore is signalled.
>
> My program essentially consists of multiple bounded-buffer queues with
one
> consumer for each queue. There is a single producer for all queues. A
queue
> is guarded by a mutex and a pair of semaphores (one to represent the # of
> unused buffers and one to represent the # of used buffers in the queue).
So
> the producer basically waits until there is a queue with unused buffer.
Then
> it produces a piece of data and puts it in that queue. So I plan to use
> WaitForMultipleObjects() to wait on all the semaphores that represent #
of
> unused buffers. The problem is that if there are more than 1 semaphores
that
> get signalled in a single WaitForMultipleObjects() call, then
> WaitForMultipleObjects() only tells you the index value of the semaphore
> with the smallest index value of all the signalled semaphores. In
general,
> there is no information returned from WaitForMultipleObjects() that could
> identify all the objects that have been signalled. You only know the one
> with the smallest index. For semaphore objects, this seems to be a
problem
> because there is no other way to find out whether other semaphores have
been
> signalled unless you call WaitForMultipleObjects() on them again. But
each
> time you wait on a semaphore, you decrease its count. So semantically,
this
> is wrong.
>
> Could anyone point out what's wrong here?
>
> -Kim
>
>
>
>
Not that I don't believe you but your point would be much more convincing if
you could point me to some documentation or KB article from MS that
discusses this issue.
Thanks,
Kim
Of course, this entire sequence, amounting to "wait for m of n objects" is
not atomic. You would need to protect the entire code block with a mutex if
atomicity (and deadlock avoidance) is an issue with several threads
performing "wait for m of n objects" concurrently.
John Hart
jmh...@world.std.com
In article <6f9ukq$14t$1...@excalibur.flash.net>,
van...@flash.net wrote:
>
> "Kim Liu" <kl...@imedia.com> wrote:
>
> >WaitForMultipleObjects() only tells you the index value of the semaphore
> >with the smallest index value of all the signalled semaphores. In general,
> >there is no information returned from WaitForMultipleObjects() that could
> >identify all the objects that have been signalled. You only know the one
> >with the smallest index. For semaphore objects, this seems to be a problem
> >because there is no other way to find out whether other semaphores have
been
> >signalled unless you call WaitForMultipleObjects() on them again. But each
> >time you wait on a semaphore, you decrease its count. So semantically, this
> >is wrong.
>
> >Could anyone point out what's wrong here?
>
> The only semaphore whose count got decremented is the lowest indexed
> one in the list of semaphores you passed in whose state was signaled
> when your thread got awaken. Just because a whole bunch of them got
> signaled doesn't mean they all decrement when you thread awakes
> (unless you specified bWaitAll to true when you made the call to
> WaitForMultipleObjects()).
>
> If five of them got signaled, you will need to call
> WaitForMultipleObjects() five times before the call blocks again
> (assuming there are no more semaphores getting released in the mean
> time).
>
>
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading
"Before returning, a wait function modifies the state of some types of
synchronization objects. Modification occurs only for the object or objects
whose signaled state caused the function to return. For example, the count of
a semaphore object is decreased by one."
The "modification occurs ONLY for the OBJECT or OBJECTS ..." seems to say it.
Of course, the documentation has been wrong before. Sounds like a nice
experiment for anyone interested.
That brings up an interesting semaphore buglet - has anyone else seen this,
or is it just me? Suppose your do ReleaseSemaphore (hSem, BigNumber,
&OldValue). The call will return a false (I want to find the current count).
But, I have found that OldValue will never exceed MaxValue-1, even when I
know the count is at the maximum. Hence, any tests of the WFMO effect on
semaphore counts will need to account for this.
Regards,
John Hart
jmh...@world.std.com
In article <6fbgql$lgu$1...@client3.news.psi.net>,
"Kim Liu" <kl...@imedia.com> wrote:
>
> > The only semaphore whose count got decremented is the lowest indexed
>
> Not that I don't believe you but your point would be much more convincing if
> you could point me to some documentation or KB article from MS that
> discusses this issue.
>
> Thanks,
> Kim
>
>
-Kim
Regards,
John Hart
jmh...@world.std.com
In article <6ff1i1$lco$1...@client3.news.psi.net>,
jmh...@world.std.com wrote in message <6fela7$c14$1...@nnrp1.dejanews.com>...
:An additional point regarding van...@flash.net's reply. You might want to
:assure that you do not wait on the decremented semaphore the next time. You
:can achieve this by shifting all the handles with a larger index one slot to
:the left in the array and decrementing the array size by one before the next
:WaitForMultipleObjects call.
Good idea! Because if you dont, no other semaphores will be able to
signal you until the one prior to it (in the array) is 0. So you organize them
by priority.
Same holds if you want to use an event to terminate a busy thread. Always
make sure the first handle in the array is your terminate event handle. If
you dont, the thread will never get the terminate signal until all prior objects
remain unsignaled.
While we are on the subject, does anyone know if windows messages
take precedence when using MsgWaitForMultipleObjects() ? My guess is
it does.