I'm trying to implement pthread_cond_wait
for 2 threads. My test code is trying to use two threads to preform the following scenario:
- Thread B waits for condition
- Thread A prints "Hello" five times
- Thread A signals thread B
- Thread A waits
- Thread B prints "Goodbye"
- Thread B signals thread A
- Loop to start (x5)
So far the code prints "Hello" five times and then gets stuck. From examples I've looked at it seems I'm on the right track, "Lock mutex, wait, get signaled by other thread, unlock mutex, do stuff, loop"
Test Code:
//Import
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
//global variables
pthread_cond_t condA = PTHREAD_COND_INITIALIZER;
pthread_cond_t condB = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *threadA()
{
int i = 0, rValue, loopNum;
while(i<5)
{
//unlock mutex
rValue = pthread_mutex_unlock(&mutex);
//do stuff
for(loopNum = 1; loopNum <= 5; loopNum++)
printf("Hello %d\n", loopNum);
//signal condition of thread b
rValue = pthread_cond_signal(&condB);
//lock mutex
rValue = pthread_mutex_lock(&mutex);
//wait for turn
while( pthread_cond_wait(&condA, &mutex) != 0 )
i++;
}
}
void *threadB()
{
int n = 0, rValue;
while(n<5)
{
//lock mutex
rValue = pthread_mutex_lock(&mutex);
//wait for turn
while( pthread_cond_wait(&condB, &mutex) != 0 )
//unlock mutex
rValue = pthread_mutex_unlock(&mutex);
//do stuff
printf("Goodbye");
//signal condition a
rValue = pthread_cond_signal(&condA);
n++;
}
}
int main(int argc, char *argv[])
{
//create our threads
pthread_t a, b;
pthread_create(&a, NULL, threadA, NULL);
pthread_create(&b, NULL, threadB, NULL);
pthread_join(a, NULL);
pthread_join(b,NULL);
}
A pointer in the right direction would be greatly appreciated, thanks! (Code compiled on Linux using "gcc timeTest.c -o timeTest -lpthread")
You have two problems. The first is that you aren't using
while()
loops correctly - for example, here:The body of the
while
loop is the statementi++
- this will executepthread_cond_wait()
andi++
until thepthread_cond_wait()
returns an error, so this is essentially an endless loop.The second is that you can't use a pthreads condition variable on its own - it needs to be paired with some actual shared state (at its simplest, this shared state might just be a flag variable protected by a mutex). The
pthread_cond_wait()
function is used to wait for the shared state to reach a certain value, and thepthread_cond_signal()
function is used when a thread has altered the shared state. Reworking your example to use such a variable:Note that the use of two condition variables
condA
andcondB
is unnecessary here - the code would be just as correct if only one condition variable was used instead.The code actually works almost fine on my machine when you add curly braces to the while loop.
Adding to what caf said, you'll enter an infinite loop when threadB is started after threadA has already sent the condB signal hence why you need to use a shared state in your while loop.
You can introduce artifical delay using
usleep(1)
on line 47 and see for yourself.