Search
The goal is to implement a program with three threads running simultaneously, where the first thread is devoted for processing input (reading pressed keys), the second thread is dedicated for updating output (single line output), the third thread implements an timer, which increments a variable after a given period, which can be controlled by the user input. In this case, pthread (POSIX threads) library is used. To do that, implement simple blocks demonstrating usage of pthread library.
pthread
void* thread1(void*); void* thread2(void*);
thread1()
counter
void* thread1(void *v) { bool q = false; /* from the <stdbool.h> */ while (!q) { usleep(100 * 1000); /* from the <unistd.h> */ counter += 1; } return 0; }
thread2()
void* thread2(void *v) { bool q = false; while (!q) { printf(*"\rCounter %10i", counter); } return 0; }
pthread_create()
counter = 0; pthread_t thrs[2]; pthread_create(&thrs[0], NULL, thread1, NULL); pthread_create(&thrs[1], NULL, thread2, NULL);
Once the thread is created, it is started and it goes to the passed function, which executed immediately.
Enter
pthread_join()
getchar(); for (int i = 0; i < 2; ++i) { pthread_join(thrs[i], NULL); }
In general, whenever we access to shared variable from multiple threads it is desirable to protect the access by a critical section, a lock that will allow only a single thread to accessing to the section. This can be implemented using mutex, i.e., pthread_mutex_t.
pthread_mutex_t
mtx
pthread_mutex_init()
pthread_mutex_t mtx; pthread_mutex_init(&mtx, NULL);
pthead_mutex_lock()
pthread_mutex_unlock()
void *thread1(void *v) { ... pthread_mutex_lock(&mtx); counter += 1; pthread_mutex_unlock(&mtx); ... }
quit
bool quit = false; ... gechar(); pthread_mutex_lock(&mtx); quit = true; pthread_mutex_unlock(&mtx); ...
void* thread1(void *v) { ... while (!q) { ... pthread_mutex_lock(&mtx); ... q = quit; ....
The current implementation of the printing loop in thread2 is computationally intensive as it is executed as fast as possible using all the available cpu resources. This is not efficient and we would like to update the line only when the variable is changed. Such a synchronization mechanism can be implemented by using conditional variable, the type pthread_cond_t, “suspend” use the execution of a thread by calling pthread_cond_wait() and signal the “suspended” thread by signaling it using pthread_cond_singnal() or pthread_cond_broadcast().
thread2
pthread_cond_t
pthread_cond_wait()
pthread_cond_singnal()
pthread_cond_broadcast()
condvar
pthread_cond_t condvar; ... pthread_cond_init(&condvar, NULL);
void* thread2(void *d) { ... pthread_mutex_lock(&mtx); ... pthread_cond_wait(&condvar, &mtx); ... pthread_mutex_unlock(&mtx); ...
pthread_cond_signal()
void* thread1(void *d) { ... pthread_mutex_lock(&mtx); counter += 1; ... pthread_cond_signal(&condvar); ... pthread_mutex_unlock(&mtx); ...
stdout
fflush(stdout);
main()
raw
"\rAlarm period: %10i Alarm counter: %10i"