Reputation: 11
#include<pthread.h>
#include<stdio.h>
int num_threads=3;
int state=0;
pthread_cond_t cond;
pthread_mutex_t mutex;
void* threadA(void* args) {
int i;
for(i=0; i<5; i++){
pthread_mutex_lock(&mutex);
while(state == 1 || state == 2) pthread_cond_wait(&cond,&mutex);
printf("Thread A\n");
state = (state+1)%num_threads;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
void* threadB(void* args) {
int i;
for(i=0; i<5; i++){
pthread_mutex_lock(&mutex);
while(state == 0 || state == 2)pthread_cond_wait(&cond,&mutex);
printf("Thread B\n");
state = (state+1)%num_threads;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
void* threadC(void* args) {
int i;
for(i=0; i<5; i++){
pthread_mutex_lock(&mutex);
while(state == 1 || state == 0) pthread_cond_wait(&cond,&mutex);
printf("Thread C\n\n");
state = (state+1)%num_threads;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
}
int main() {
pthread_t tid[3];
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL);
pthread_create(&tid[0],NULL,threadA,NULL);
pthread_create(&tid[1],NULL,threadB,NULL);
pthread_create(&tid[2],NULL,threadC,NULL);
return 0;
}
QUESTION: With the above code, I wish to print threaA threadB threadC sequentially 5 times. But the answer is undeterministic. While the order of threads is maintained, answers are not printed 5 times. Please help!!!
Upvotes: 1
Views: 100
Reputation: 6866
As @mch mentioned in the comment, you need to wait for the threads to finish before allowing the main()
function to return:
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_join(tid[2], NULL);
Now, after you add the joins above to the end of main()
, your program will most often hang. This happens because the pthread_cond_signal()
doesn't wake up all threads waiting on that condition variable. If the wrong thread is woke up (e.g. threadC signals the condition, but the thread that gets notified is not threadA), then all threads will be waiting on the condition and there will be nobody to signal that condition.
To fix this, you need to make sure all threads are woke up each time and let each thread decide on it's own if it is its turn or not (by that while(state...) pthread_cond_wait(...);
). To do this, you can replace the calls to pthread_cond_signal()
with calls to pthread_cond_broadcast()
, which unblocks all threads currently blocked on that condition.
Upvotes: 3