Applying C - Condition Variables |
Written by Harry Fairhead | ||||||
Monday, 12 November 2018 | ||||||
Page 2 of 2
In the main program we need to declare the mutex, condition variable and the global variable: pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t myConVar = PTHREAD_COND_INITIALIZER; int threadid=0; The main program starts the two threads going and then waits: int main(int argc, char** argv) { srand(time(0)); pthread_t pthreadA; pthread_create(&pthreadA, NULL, threadA, NULL); pthread_t pthreadB; pthread_create(&pthreadB, NULL, threadB, NULL); pthread_mutex_lock(&my_mutex); while (threadid == 0) Notice that the call to pthread_cond_wait is in the form of a while loop. The reason is that the wait can end without any thread signaling. To make sure that it isn’t a spurious wake-up we have to check that threadid has been set to something other than zero. If it is still zero then the wait is restarted. Finally we print the value of threadid and unlock the mutex. Notice you can’t unlock the mutex until the value of threadid has been printed as one of the other threads might update it. The complete program is: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t myConVar = PTHREAD_COND_INITIALIZER; int threadid = 0; void * threadA(void *p) { sleep(rand() % 5); pthread_mutex_lock(&my_mutex); threadid = 1; pthread_cond_signal(&myConVar); pthread_mutex_unlock(&my_mutex); } void * threadB(void *p) { sleep(rand() % 5); pthread_mutex_lock(&my_mutex); threadid = 2; pthread_cond_signal(&myConVar); pthread_mutex_unlock(&my_mutex); } int main(int argc, char** argv) { srand(time(0)); pthread_t pthreadA; pthread_create(&pthreadA, NULL, threadA, NULL); pthread_t pthreadB; pthread_create(&pthreadB, NULL, threadB, NULL); pthread_mutex_lock(&my_mutex); while (threadid == 0) Now that you have seen how this works you should be able to modify the program so that the main program only resumes when all of the threads have completed. All you have to do is change the update of the global variable and the signal to: threadid++; if(threadid==2) pthread_cond_signal(&myConVar); With this change each thread increments the global variable but only wakes the main thread up when it reaches 2 and both threads have terminated. You might want to use this in place of joins if you want to create detached threads. Now available as a paperback or ebook from Amazon.Applying C For The IoT With Linux
Also see the companion book: Fundamental C <ASIN:1871962609> <ASIN:1871962617> Related ArticlesRemote C/C++ Development With NetBeans Getting Started With C/C++ On The Micro:bit To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info |
||||||
Last Updated ( Sunday, 09 June 2019 ) |