Mutexes are used to ensure the exclusive access , where as condition variables are used to synchronize threads based on the events.
We need Mutexes to ensure that condition variables dont end up in an infinite wait.
One thing to remember is Mutex operation of lock and unlock are guaranteed to be atomic, but the condition variables need not be. i.e The thread can get scheduled out while the condition variable wait is half way.
Consider the following case with out Mutex for condition variable.
Thread 1
1)Perform Some Operation
2)Wait on the Condition Variable
3)Continues the Operation
Thread 2
1) Perform some operation
2)Signal the Condition Variable
3)Continue the Operation
Here in the Thread 1 , the step 2 is not guaranteed to be atomic. If the Thread 1 is pushed out of RUNNING state by scheduler before it completes the step1.
Now Thread 2 starts executing and signals the condition variable. When Thread 1 resumes execution it will finish the remaining low level instructions and starts waiting.
Thread 1 ends up in an infinite wait, as the signal of condition variable occurred even before the wait.
So the Right way to use is (I believe the code mentioned in the question doesnt do the expected)
Thread 1 :-
1)Do work up to the point where a certain condition must occur (such as "count" must reach a specified value)
2)Lock associated mutex
3)Call pthread_cond_wait() to perform a blocking wait for signal from Thread1.
( Note that a call to pthread_cond_wait() automatically and atomically unlocks the associated mutex variable so that it can be used by Thread2)
4)When signalled, wake up. Mutex is automatically and atomically locked.
5)Explicitly unlock mutex
Thread2
1)Do work
2)Lock associated mutex
3)Change the value of the global variable that Thread1 is waiting upon.
4)Check value of the global Thread1 wait variable. If it fulfills the desired condition, signal Thread1.
5)Unlock mutex.
Continue