C++ Tutorial
Quiz - Multithreading - 2020
Q: Write a multi threaded C code with one thread printing all even numbers and the other all odd numbers. The output should always be in sequence ie. 0,1,2,3,4....etc.
The following program may not work:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> int MAX = 10; int count = 0; void *even(void *arg) { printf("This is even thread()\n"); while(count < MAX) if(count % 2 == 0) printf("%d ", count++); pthread_exit(0); } void *odd(void *arg) { printf("This is odd thread()\n"); while(count < MAX) if(count % 2 == 1) printf("%d ", count++); pthread_exit(0); } int main() { pthread_t t1; pthread_t t2; pthread_create(&t1;, 0, &even;, NULL); pthread_create(&t2;, 0, &odd;, NULL); pthread_join(t1, 0); pthread_join(t2, 0); return 0; }
Output:
1 0 2 3 4 5 6 7 9 8or
1 0 2 4 3 5 6 7 8 9
There is no consistency in the output.
So, we need to modify the code like this:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> int MAX = 10; int count = 0; pthread_mutex_t mutex; pthread_cond_t cond; void *even(void *arg) { while(count < MAX) { pthread_mutex_lock(&mutex;); while(count % 2 != 0) { pthread_cond_wait(&cond;, &mutex;); } printf("%d ", count++); pthread_mutex_unlock(&mutex;); pthread_cond_signal(&cond;); } pthread_exit(0); } void *odd(void *arg) { while(count < MAX) { pthread_mutex_lock(&mutex;); while(count % 2 != 1) { pthread_cond_wait(&cond;, &mutex;); } printf("%d ", count++); pthread_mutex_unlock(&mutex;); pthread_cond_signal(&cond;); } pthread_exit(0); } int main() { pthread_t t1; pthread_t t2; pthread_mutex_init(&mutex;, 0); pthread_cond_init(&cond;, 0); pthread_create(&t1;, 0, &even;, NULL); pthread_create(&t2;, 0, &odd;, NULL); pthread_join(t1, 0); pthread_join(t2, 0); pthread_mutex_destroy(&mutex;); pthread_cond_destroy(&cond;); return 0; }
The output looks like this:
0 1 2 3 4 5 6 7 8 9 10
The key components of the locking and condition checking are:
// for even() thread function pthread_mutex_lock(&mutex;); (lock before checking) check wait until count becomes even (pthread_cond_wait(&cond;, &mutex;) - wait for signal from another thread) do something (print and count++) pthread_mutex_unlock(&mutex;); (release) pthread_cond_signal(&cond;); (signal to another thread)
When a thread calls pthread_cond_wait(&cond;, &mutex;), it releases the mutex and it waits till condition cond is signaled as complete and mutex is available.
Note that pthread_cond_signal(&cond;) does not have mutex as an argument while pthread_cond_wait(&cond;, &mutex;) has it.
pthread_cond_signal() does not unlock the mutex, and it can't. In fact, it does not need mutex. However, pthread_cond_wait() unlocks the mutex just before it sleeps, but then it reaquires the mutex (which may require waiting) when it is signalled, before it wakes up. So if the signalling thread holds the mutex (the usual case), the waiting thread will not proceed until the signalling thread also unlocks the mutex.
Bogotobogo's contents
To see more items, click left or right arrow.
Bogotobogo Image / Video Processing
Computer Vision & Machine Learning
with OpenCV, MATLAB, FFmpeg, and scikit-learn.
Bogotobogo's Video Streaming Technology
with FFmpeg, HLS, MPEG-DASH, H.265 (HEVC)
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization