There are a mess of postings and answers on this topic, but none seems to quite model my problem. After poking around googling and searching stackoverflow, I don't quite see the answer for my question.
I have two threads, a master and slave. The slave needs to wait for the master before proceeding past a certain point, so I've created a mutex as a global variable:
pthread_mutex_t lock;
And then in the initialization for the master thread, long before the slave thread can have a chance to access it, I lock it:
initialize in master thread:
pthread_mutex_lock(&lock)
Then in the slave, when its time to wait for the master I do this:
slave must wait here:
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
Meanwhile, back in the master, I have this when its time to "release" the slave who is blocked waiting:
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
(Note: the order of lock/unlock is opposite for the master.)
Based on my understanding of mutexes, I figured the slave would hit the lock, and get stuck there waiting for the master who would unlock it, then immediately lock it again. In terms of timing, the slave will take a LONG time (guaranteed) to get back here again, so the master will have lots of time to relock it. Similarly, the master won't get back here again for a while and we don't need to worry about either the master or the slave beating the other back to these checkpoints.
When it did not work as expected, I tossed in some printf's to confirm that the master unlocks, then re-locks the mutex before the slave can unlock it. My understanding is that the slave has requested the lock long before the master got there to do the unlock and (re)lock, and no matter how small the time is between the master's unlock and (re) lock, the slave should still be able to lock the mutex because he's already been "in line" waiting.
However, what I see happening is that the master unlocks the mutex, and then immediately re-locks it even though the slave has been patiently blocked waiting for his chance to lock it.
Here is the code with the printf's in it and the output generated:
slave:
printf("slave thread starting lock sequence\n");fflush(stdout);
pthread_mutex_lock(&lock);
printf("slave thread intra lock sequence\n");fflush(stdout);
pthread_mutex_unlock(&lock);
printf("slave thread completed lock sequence\n");fflush(stdout);
master:
printf("master thread starting lock sequence\n");fflush(stdout);
pthread_mutex_unlock(&lock);
printf("master thread intra lock sequence\n");fflush(stdout);
pthread_mutex_lock(&lock);
printf("master thread completed lock sequence\n");fflush(stdout);
Now here's what I see as output:
slave thread starting lock sequence
... then some time goes by (several seconds) while the slave is blocked, and finally this appears:
master thread starting lock sequence
master thread intra lock sequence
master thread completed lock sequence
In the meantime, there is no further progress of the slave, who remains blocked forever. I would have expected him to prevent the master from re-locking and should have spit out his printf indicating that he'd moved forward. This output clearly indicates that the blocked slave didn't get his chance to lock the mutex even though he was patiently waiting in line for his turn.
So what is it that I am missing about mutexes and lock/unlock?
-gt-