Code Comments
Programming Forum and web based access to our favorite programming groups.Everything I read about using pthread_cond_wait shows code example
such as this (pseudo-ish code):
int value = 1;
pthread_cond_t cond;
pthread_mutex_t mutex;
void set_value_to_0 () {
pthread_mutex_lock(&mutex);
value = 0;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
void wait_for_0_value () {
pthread_mutex_lock(&mutex);
while (value != 0)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
}
I know this is explained in various documentation but for some reason
I am still having a really hard time wrapping my head around it: why
do I have to loop on "while (value != 0)" when calling
pthread_cond_wait...? I set the value to 0 then signal the condition
variable. What kind of situations could happen that would make value
not be 0 after the condition variable was signalled?
Thanks,
AJ
Post Follow-up to this messageadramolek@gmail.com wrote: > > I know this is explained in various documentation but for some reason > I am still having a really hard time wrapping my head around it: why > do I have to loop on "while (value != 0)" when calling > pthread_cond_wait...? I set the value to 0 then signal the condition > variable. What kind of situations could happen that would make value > not be 0 after the condition variable was signalled? > There is no guarantee you will not get a spurious wakeup. -- Ian Collins.
Post Follow-up to this messageThanks for your reply.
On Mar 25, 2:46 am, Ian Collins <ian-n...@hotmail.com> wrote:
> adramo...@gmail.com wrote:
>
>
> There is no guarantee you will not get a spurious wakeup.
I see... from a signal or something? It seems so much simpler when you
say it than reading through the man pages... but wouldn't that be
reflected by the return code of pthread_cond_wait? I.e., why can't I
do this:
pthread_mutex_lock(&mutex);
while (pthread_cond_wait(&cond, &mutex) != 0)
;
pthread_mutex_unlock(&mutex);
This one man page I'm reading says "these functions will not return an
error code of [EINTR]"; but that seems arbitrary (although I'm sure
it's not)?
Are there predictable ways to trigger "spurious wakeups"? Like, for
example, what if I had a pthread_cond_wait, and I wanted to "abort"
that from another thread, maybe so I could do something like:
pthread_mutex_lock(&mutex);
while (!condition) {
int e = pthread_cond_wait(&cond, &mutex);
if (e == EMAGICALLYABORTED) { /* do something */ }
}
pthread_mutex_unlock(&mutex);
Or, more specifically, let's say I was doing something like this:
// init some stuff, then...
while (!somequitflag) {
pthread_mutex_lock(&mutex);
while (!condition)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
}
// ... then clean stuff up
How could I keep that thread responsive to a change in somequitflag? I
see pthread_cancel, but it says it terminates the thread, but I don't
want to terminate the thread, I want to clean stuff up.
Thanks,
AJ
Post Follow-up to this messageadramolek@gmail.com wrote: > Thanks for your reply. > > On Mar 25, 2:46 am, Ian Collins <ian-n...@hotmail.com> wrote: > > I see... from a signal or something? It seems so much simpler when you > say it than reading through the man pages... but wouldn't that be > reflected by the return code of pthread_cond_wait? I.e., why can't I > do this: > > pthread_mutex_lock(&mutex); > while (pthread_cond_wait(&cond, &mutex) != 0) > ; > pthread_mutex_unlock(&mutex); > > This one man page I'm reading says "these functions will not return an > error code of [EINTR]"; but that seems arbitrary (although I'm sure > it's not)? > On some systems, I believe a signal sent to the process my cause the spurious wakeup. There's a reasonably informative Wikipedia article here: http://en.wikipedia.org/wiki/Spurious_wakeup For more information, comp.programming.threads is the best place to ask. -- Ian Collins.
Post Follow-up to this messageadramolek@gmail.com writes:
> Everything I read about using pthread_cond_wait shows code example
> such as this (pseudo-ish code):
>
> int value = 1;
> pthread_cond_t cond;
> pthread_mutex_t mutex;
>
> void set_value_to_0 () {
> pthread_mutex_lock(&mutex);
> value = 0;
> pthread_cond_broadcast(&cond);
> pthread_mutex_unlock(&mutex);
> }
>
> void wait_for_0_value () {
> pthread_mutex_lock(&mutex);
> while (value != 0)
> pthread_cond_wait(&cond, &mutex);
> pthread_mutex_unlock(&mutex);
> }
>
> I know this is explained in various documentation but for some reason
> I am still having a really hard time wrapping my head around it: why
> do I have to loop on "while (value != 0)" when calling
> pthread_cond_wait...?
Because the interface documentation says so.
Post Follow-up to this messageadramolek@gmail.com writes:
> Everything I read about using pthread_cond_wait shows code example
> such as this (pseudo-ish code):
>
> int value = 1;
> pthread_cond_t cond;
> pthread_mutex_t mutex;
>
> void set_value_to_0 () {
> pthread_mutex_lock(&mutex);
> value = 0;
> pthread_cond_broadcast(&cond);
> pthread_mutex_unlock(&mutex);
> }
>
> void wait_for_0_value () {
> pthread_mutex_lock(&mutex);
> while (value != 0)
> pthread_cond_wait(&cond, &mutex);
> pthread_mutex_unlock(&mutex);
> }
>
> I know this is explained in various documentation but for some reason
> I am still having a really hard time wrapping my head around it: why
> do I have to loop on "while (value != 0)" when calling
> pthread_cond_wait...? I set the value to 0 then signal the condition
> variable. What kind of situations could happen that would make value
> not be 0 after the condition variable was signalled?
There is a simpler reason as yet not explained...
The waiting thread has released the mutex while it is suspended (you
should be able to see that is required -- no thread would ever be able
to signal that value == 0 if the mutex were held by waiting threads).
Assume that there are several threads waiting on the same cond_var.
When a thread finally signals cond_broadcast, more than one thread may
be signalled (and certainly will be if more than one thread is
waiting). These threads will all be runnable, but only one will get
the mutex. Presumably that thread will "destroy" the situation where
value == 0 (you don't show that in your pseudo-code) but eventually it
will leave the critical section protected by the mutex and one of the
other awakened threads will claim it. It will find that value != 0
(the other thread got there first) so it must wait again. If it did
not test, it would assume (incorrectly) that the situation indicated
by the condition variable still existed.
This is just a logical consequence of the design. It is not the same
as spurious wake-up, although the solution is the same. Spurious
wake-up is the inadvertent signaling of more than one thread by
cond_signal.
Even without the possibility of spurious wake-up, the while loop is
correct /even when using cond_signal/ because many algorithms use
cond_signal in such a way that you must re-test. For example, a
thread will put data on a queue and signal "not empty". It may do so
three times before the first awakened consumer thread gets going.
That consumer may eat all the available data so the other threads,
awakened by the other two "not empty" signals must test the real
condition -- they will find the queue is empty again despite having
been signaled.
--
Ben.
Post Follow-up to this messageIan Collins <ian-news@hotmail.com> writes: > adramolek@gmail.com wrote: > On some systems, I believe a signal sent to the process my cause the > spurious wakeup. There's a reasonably informative Wikipedia article here: > > http://en.wikipedia.org/wiki/Spurious_wakeup Spurious wake-up are, I feel, something of a red herring, here. The OP is using cond_broadcast, so multiple threads being awakened are inevitable even if the implementation can avoid spurious wake-ups from pthread_cond_signal. -- Ben.
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.