
on the mac the notion of a semaphore is at a slightly higher level than a condition_variable. but it seems in boost::thread we must use the actual condition_variable. on the mac, with a semaphore, the value can be pre-set to signal, so that the next wait() is passed right thru, since the signal was sent ahead of time. eg: you could do this: Semaphore sem; // newly initialized semaphore, brand new, never waited upon sem.signal(); // you can pre-set the signal! // later in the code sem.wait(); // no wait, since signal was already sent // and later still sem.wait(); // now we wait in fact, actually, the way it actually happens on the mac is that a newly initialized semaphore comes IN WITH the semaphore pre-signaled. so you actually have to call wait() immediately to eat that signal. i've got lots of code that does this: Semaphore sem; sem.wait(); // eat the first signal i thought that was normal. trouble is,i've got lots of code that does NOT eat that first signal, depending on the first wait call to be passed thru immediately. this is the code that now breaks. in converting to boost::thread, there doesn't seem to be a way to pre- set the signal. or to reset the state of a semaphore from an unknown state to a known state, eg this code: sem.signal(); sem.signal(); sem.wait(); that guarantees that the next wait will actually wait, regardless of the state of the sem before hand. how can i do this with boost::thread ?

AMDG David M. Cotter wrote:
on the mac the notion of a semaphore is at a slightly higher level than a condition_variable.
but it seems in boost::thread we must use the actual condition_variable.
on the mac, with a semaphore, the value can be pre-set to signal, so that the next wait() is passed right thru, since the signal was sent ahead of time.
eg: you could do this:
Semaphore sem; // newly initialized semaphore, brand new, never waited upon
sem.signal(); // you can pre-set the signal!
// later in the code sem.wait(); // no wait, since signal was already sent
// and later still sem.wait(); // now we wait
in fact, actually, the way it actually happens on the mac is that a newly initialized semaphore comes IN WITH the semaphore pre-signaled. so you actually have to call wait() immediately to eat that signal.
i've got lots of code that does this:
Semaphore sem;
sem.wait(); // eat the first signal
i thought that was normal. trouble is,i've got lots of code that does NOT eat that first signal, depending on the first wait call to be passed thru immediately. this is the code that now breaks.
in converting to boost::thread, there doesn't seem to be a way to pre-set the signal. or to reset the state of a semaphore from an unknown state to a known state, eg this code:
sem.signal(); sem.signal(); sem.wait();
that guarantees that the next wait will actually wait, regardless of the state of the sem before hand.
how can i do this with boost::thread ?
A condition variable doesn't have state. If you call wait, you will always block until another thread calls notify_one or notify_all. notify_one and notify_all have no effect if no threads are waiting. In Christ, Steven Watanabe

how can i do this with boost::thread ?
A condition variable doesn't have state. If you call wait, you will always block until another thread calls notify_one or notify_all. notify_one and notify_all have no effect if no threads are waiting.
well that completely explains it :) thanks. i've added that state to my class and now it's working great. thanks again!

On 10/7/09, David M. Cotter <me@davecotter.com> wrote:
how can i do this with boost::thread ?
A condition variable doesn't have state. If you call wait, you will always block until another thread calls notify_one or notify_all. notify_one and notify_all have no effect if no threads are waiting.
well that completely explains it :)
thanks. i've added that state to my class and now it's working great. thanks again!
If boost threads doesn't have a semaphore, we could add one. Is the mac one a counting semaphore? Or just a single, like windows 'events'? We could add both actually. The manual reset, preset/passthru, etc properties come in handy at times. They can of course be implemented by the client on top of what is already there, but if it is common and useful, it could be part of the lib. A library level impl could also make better use of OS level support. Tony

Gottlob Frege wrote:
If boost threads doesn't have a semaphore, we could add one.
boost::thread doesn't have a semaphore for a purpose. boost::threads is modelled after the pthreads API, which does not need what you are seeking for. Perhaps you could look up a book on pthreads for an in depth explanation? For short in pthreads API the state and the notification are decoupled, which is a more general aproach. Of course you know it, but it is straight forward to get the equivalent of a semaphore with boost::threads. Something like (details omitted): mutex mx; int count = 42; codition c; ... //acquire { lock(mx); while (0==count) c.wait(mx); --count; } ... //release { lock(mx); ++count; c.notify_all(); } Regards, Roland -- _________________________________________ _ _ | Roland Schwarz aka. speedsnail |_)(_ | sip:speedsnail@ekiga.net | \__) | mailto:roland.schwarz@chello.at ________| http://www.blackspace.at

Roland Schwarz wrote:
Gottlob Frege wrote:
If boost threads doesn't have a semaphore, we could add one.
boost::thread doesn't have a semaphore for a purpose. boost::threads is modelled after the pthreads API, which does not need what you are seeking for. Perhaps you could look up a book on pthreads for an in depth explanation? For short in pthreads API the state and the notification are decoupled, which is a more general aproach.
Of course you know it, but it is straight forward to get the equivalent of a semaphore with boost::threads.
Isn't it reasonable for a library to provide helpful, tested, reusable, and documented functionality? I'm not arguing whether semaphores are an appropriate abstraction or whether their presence would encourage programming styles that should be discouraged. Those are separate questions. I'm merely arguing that eschewing a feature because it is fairly straightforward given the provided functionality is weak at best. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Stewart, Robert wrote:
Roland Schwarz wrote:
Gottlob Frege wrote:
If boost threads doesn't have a semaphore, we could add one. boost::thread doesn't have a semaphore for a purpose. boost::threads is modelled after the pthreads API, which does not need what you are seeking for. Perhaps you could look up a book on pthreads for an in depth explanation? For short in pthreads API the state and the notification are decoupled, which is a more general aproach.
Of course you know it, but it is straight forward to get the equivalent of a semaphore with boost::threads.
Isn't it reasonable for a library to provide helpful, tested, reusable, and documented functionality?
I'm not arguing whether semaphores are an appropriate abstraction or whether their presence would encourage programming styles that should be discouraged. Those are separate questions. I'm merely arguing that eschewing a feature because it is fairly straightforward given the provided functionality is weak at best.
I'm not sure why the rationale and FAQ sections of the thread library docs have been lost with later versions of the thread library, but the following was in boost 1.31.0: 10. Why has class semaphore disappeared? Semaphore was removed as too error prone. The same effect can be achieved with greater safety by the combination of a mutex and a condition variable. Dijkstra (the semaphore's inventor), Hoare, and Brinch Hansen all depreciated semaphores and advocated more structured alternatives. In a 1969 letter to Brinch Hansen, Wirth said "semaphores ... are not suitable for higher level languages." [Andrews-83] summarizes typical errors as "omitting a P or a V, or accidentally coding a P on one semaphore and a V on on another", forgetting to include all references to shared objects in critical sections, and confusion caused by using the same primitive for "both condition synchronization and mutual exclusion". Jeff

On Wed, Oct 7, 2009 at 12:41 PM, Roland Schwarz <roland.schwarz@chello.at> wrote:
Gottlob Frege wrote:
If boost threads doesn't have a semaphore, we could add one.
boost::thread doesn't have a semaphore for a purpose. boost::threads is modelled after the pthreads API,
only to a certain point, I would say.
which does not need what you are seeking for. Perhaps you could look up a book on pthreads for an in depth explanation?
I'm quite familiar with pthreads. (Even made a small contribution to pthreads-win32! Not that that actually proves familiarity, I suppose.) Also note that most POSIX implementations *do* have semaphores, whether they are formally part of pthreads or not. Often, of course, this is because the sema is at a different level then pthreads (ie callable from interrupts, etc. Not that I'm suggesting we should attempt something like that!)
For short in pthreads API the state and the notification are decoupled, which is a more general aproach.
Definitely. And usually the better approach. But being more general just means more possible uses. It doesn't mean that a more specific construct isn't better in a certain case. The question is whether that case is common enough. Personally, I don't like semas much - the descriptions and terminology, in particular, tend to make them confusing and error-prone. But maybe we could rectify that. For a binary semaphore (ie Windows 'event') they can at times be useful. ie for call_once() implementations, once the initial mutual exclusion (ie the 'once' part) has been done, there is no need to re-grab the mutex - all the 'waiters' really do is wait on the "done" event. And then they can ALL go forward. In the current boost impl, each waiter wakes up, grabs the mutex, then immediately lets it go again. A binary semaphore would work better here. (In fact, depending on the internals, it may be that ALL the waiters wake up, race for the mutex, all but one go back to waiting, 'winner' grabs mutex and immediately frees it, repeat until waiters == 0...) But maybe that's the only good example, and it is burried inside boost::threads already. The original boost rationale (posted further down by Jeff Flinn) maybe makes more sense. Although I don't agree with all of it. (For example "forgetting to include all references to shared objects in critical sections" is a common error for all threading, not just semaphores.) Lastly, also note that most unix systems have things like select() making semaphores less useful, whereas Windows might use Events in those cases. Anyhow, I'm not actually arguing that strongly for semaphores. It was just a suggestion. In 15 years of threading, I think I've only used a counting semaphore once. Events moreso, but mostly because I was stuck on Windows.
Regards, Roland
Tony
participants (6)
-
David M. Cotter
-
Gottlob Frege
-
Jeff Flinn
-
Roland Schwarz
-
Steven Watanabe
-
Stewart, Robert