Hi all,
I would like to know if my understanding on how the program handles
pthread_cond_wait() and pthread_cond_signal() is correct.
Given the code below,
// Thread A
while (1)
{
do_Awork();
signal = 1;
pthread_cond_signal(&condition);
signal = 0;
}
// Thread B, C, D
while (1)
{
pthread_mutex_lock(&mutex);
while (!signal)
pthread_cond_wait(&condition, &mutex);
do_BCDwork();
pthread_mutex_unlock(&mutex);
}
"mutex" and"condition" are global variables that have been
initialized. "signal" is also a global variable that has been
initialized to 0. The program should only execute do_BCDwork() in
Thread B, C and D when Thread A finishes do_Awork() and changes signal
to 1. Then Thread A signals either Thread B, C or D, sets signal to 0
again and repeat the whole process.
I would like to understand the flow and logic of the above code, and
please tell me if I misunderstood anything.
I'll start with say, Thread B that enters the while(1) loop, locks
mutex and enters the while (!signal) loop, which is true and so it
calls pthread_cond_wait(), at the same time unlocking the mutex. Now
Thread C goes into the while(1) loop, locks the mutex, enters the
while (!signal) loop, which is true and it calls pthread_cond_wait(),
at the same time unlocking the mutex. Sane thing happens to Thread D.
So we now have all three threads waiting at pthread_cond_wait().
Say, at this point Thread A enters its while(1) thread, runs
do_Awork(), then sets signal = 1. It then calls pthread_cond_signal()
and say, Thread C gets woken up. (Any of the three threads can get
signaled, right? It need not be in the order they called
pthread_cond_wait()?)
Thread C, after waking up, returns from pthread_cond_wait() and checks
the while(!signal) loop, which is now false and so it goes out of that
while loop, locks the mutex and runs do_BCDwork(). Thread A sets
signal back to 0. (One question, could Thread A set signal = 0 faster
than Thread C checking the while(!signal) loop, hence, resulting in
Thread C calling pthread_cond_wait() again since the while-loop
condition is not met? If so, should I put a usleep(100) before signal
= 0 so that this won't happen?)
After running do_BCDwork(), Thread C unlocks the mutex. Then it locks
the mutex again since it has to stay in the while(1) loop, checks that
while(!signal) is true and calls pthread_cond_wait(). This process
repeats itself, only either Thread, B, C or D can be woken up each
time Thread A sets signal = 1.
Is my understanding of the logic correct? What other things should I
look out for?
Also, this shouldn't be a one-to-one "relation****p", that is, Thread A
wakes up one thread, that thread finishes do_BCDwork(), goes into
pthread_cond_wait(), then Thread A wakes up another thread, that
thread finishes do_BCDwork(), goes into pthread_cond_wait(), and so
on. The program should have Thread A wake up one thread, that thread
finishes do_BCDwork(), and while that is happening, another thread can
be woken up by Thread A and it carries out do_BCDwork() too. (The
variables in do_BCDwork() are kept different so different threads can
carry out do_BCDwork() independently and not interfere/change anything
the other threads are working on.) However, I realize that if this
were to happen, say Thread C gets woken up first, it would lock the
mutex wile it does do_BCDwork(). If Thread B were also to get woken up
at this time, it would also try to lock the mutex that Thread C is
holding, in order to execute do_BCDwork(), which would give me an
error (This might be why I keep getting "Segmentation fault" in my
program). Is there some way to workaround this?
Thank you.
Regards,
Rayne


|