The problem I am seeking some help for is written in point no. 7. Before that, I describe the structure of my code.
- From
main()
, two threads thread1 and thread2 are created and initialized to two functionsfun1()
andfun2()
respectively. - I have a mutex named
lock_mutex
and condition v开发者_JAVA百科ariables namedcond1
,cond2
,cond3
andcond4.
- I have global boolean variables
var1
,var2
,var3
andvar4
all initialized to false. fun1()
is like the following:void fun1(){ while(1){ pthread_mutex_lock(&lock_mutex); while(var1 is false) pthread_cond_wait(&cond1,&lock_mutex); //do some work set var3 = true; pthread_cond_signal(&cond3); set var1=false; pthread_mutex_unlock(&lock_mutex); } }
fun2()
is as following:void fun2(){ while(1){ pthread_mutex_lock(&lock_mutex); while(var2 is false) pthread_cond_wait(&cond2,&lock_mutex); //do some work set var4 = true; pthread_cond_signal(&cond4); set var2=false; pthread_mutex_unlock(&lock_mutex); } }
- There are functions in my code which hold
lock_mutex
, do some work and signalcond1
andcond2
when appropriate, like this (each is a separate function):
function A:
pthread_mutex_lock(&lock_mutex);
//do some work
set var1= true;
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&lock_mutex);
function B:
pthread_mutex_lock(&lock_mutex);
//do some work
set var2= true;
pthread_cond_signal(&cond2);
pthread_mutex_unlock(&lock_mutex);
function C:
pthread_mutex_lock(&lock_mutex)
//do some work
while(var3 is false)
pthread_cond_wait(&cond3,&lock_mutex);
//do more work
set var3=false;
pthread_mutex_unlock(&lock_mutex);
function D:
pthread_mutex_lock(&lock_mutex)
//do some work
while(var4 is false)
pthread_cond_wait(&cond4,&lock_mutex);
//do more work
set var4= false;
pthread_mutex_unlock(&lock_mutex);
7.fun1()
and fun2()
are signaled repeatedly by function A and function B. I expect fun1()
and fun2()
to call function C and function D each time they are signaled.
But fun1()
and fun2()
are being woken up only for the first time. After that, they enter the while loop, acquire the lock and wait for the signal indefinitely and don't wake up despite signaling.
I am not being able to understand the cause of this problem and would be very thankful to any suggestion. If any good debugging techniques/tools for this kind of program is available, kindly refer me to them too.
With many thanks in advance.
The answer to Mr. Graves's question is that pthread_cond_wait automatically unlocks the mutex while blocking.
It sounds like a deadlock.
If one thread acquires a mutex lock and then waits for a variable to get set, how does another thread acquire the mutex lock to set the variable?
Signaling a condition variable doesn't mean the blocking thread acquires the lock and starts running immediately, it means it's awakened, and when the scheduler wishes, it will give the blocking thread CPU time.
So, what I think happens here is the following:
function B
signalscond2
.fun2
is awakened, setsvar4
to true, signalscond4
, setsvar2
to false, releases the mutex.fun2
reacquires the mutex, and rereleases it, waiting oncond2
forvar2
to become true.function B
gets the mutex, setsvar2
to true, signalscond2
fun2
is awakened, setsvar4
to true, signalscond4
, setsvar2
to false, releases the mutex.- Now two signalings of
cond4
have been collapsed into one.
精彩评论