Reputation: 1267
Let's imagine there is a thread which calls pthread_cond_wait
and waits for signals:
pthread_mutex_lock(&m);
.....
while(run)
{
do {
pthread_cond_wait(&cond,&m);
} while(!got_signal);
got_signal = false;
do_something();
}
And there are multiple threads which are supposed to deliver signals:
pthread_mutex_lock(&m);
got_signal = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&m);
Is this solution safe enough? What will happen if multiple threads send signals? Does m
mutex suffice to guarantee all signals are serialized and won't be lost?
Upvotes: 1
Views: 3196
Reputation: 6092
In the code you posted, the only place where threads are allowed to call pthread_cond_signal()
is when they can acquire m
, and that can only happen when your waiting thread is blocked on pthread_cond_wait()
.
However, it might happen that two signaling threads acquire the mutex after each other, before the waiting thread is woken up and can acquire the mutex. In that case you'll lose the second signal (and any further signals that might arrive after that, before the waiting thread runs), since your waiting thread can only "see" that it has been signaled, but not how many times this has happened.
To make sure that you don't lose any signals, you could use a counter instead of your got_signal
flag:
Waiting thread:
pthread_mutex_lock(&m);
.....
while(run)
{
while(signal_count == 0) {
pthread_cond_wait(&cond,&m);
}
--signal_count;
do_something();
}
Signaling threads:
pthread_mutex_lock(&m);
++signal_count;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&m);
(Also note that I've exchanged the do...while
loop with a while
loop, to make sure that pthread_cond_wait()
isn't called if there's still an unprocessed signal left.)
Now, if multiple threads end up signaling straight after each other, signal_count
will become more than one, which will cause the waiting thread to run its do_something()
multiple times instead of just once.
Upvotes: 3