Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Semaphore and WaitForMultipleObjects

0 views
Skip to first unread message

Kim Liu

unread,
Mar 24, 1998, 3:00:00 AM3/24/98
to

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


Van Chinh Ly

unread,
Mar 25, 1998, 3:00:00 AM3/25/98
to

"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).

dave porter

unread,
Mar 25, 1998, 3:00:00 AM3/25/98
to

After WaitForMultipleObjects on N semaphores returns (assuming you're
waiting on 'one' and not 'all', then precisely one semaphore's count
will have been decremented. Which one it is will be indicated
by the return code.

(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
>
>
>
>

Kim Liu

unread,
Mar 25, 1998, 3:00:00 AM3/25/98
to

> 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

jmh...@world.std.com

unread,
Mar 26, 1998, 3:00:00 AM3/26/98
to

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.

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

jmh...@world.std.com

unread,
Mar 26, 1998, 3:00:00 AM3/26/98
to

Kim, this is not totally definitive, but the VC++ 5.0 remarks at the end of
the WFMO entry does say:

"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 Liu

unread,
Mar 26, 1998, 3:00:00 AM3/26/98
to

Well, the statement you quoted from the documentation is exactly why I
worried in the first place. It says the state modification occurs for the
object or objects whose signaled state caused the function to return. This
means (to me) that if 2 semaphores got signaled during the wait, then both
will be decremented. But I am pretty sure this is not the case after I did
my experiment. Only the semaphore indicated in the return code is
decremented. This makes perfect sense. Otherwise you won't be able to find
out which semaphores (if more than 1) were decremented. Same thing should go
for mutex. So, I think this is just a documentation bug.

-Kim


jmh...@world.std.com

unread,
Mar 27, 1998, 3:00:00 AM3/27/98
to

Kim, I think we are in agreement. I found the WaitForMultipleObjects
documentation to be slightly ambiguous as well, but my initial interpretation
was that the lowest-index semaphore was the one that "caused" the return. At
any rate, your experiments indicate that it operates the way we would like it
to.

Regards,

John Hart
jmh...@world.std.com

In article <6ff1i1$lco$1...@client3.news.psi.net>,

Troy

unread,
Mar 27, 1998, 3:00:00 AM3/27/98
to

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.

0 new messages