POSIX C Threads. pthread_cond_t example. Doesn't work as expected

c++, conditional-statements, multitasking, pthreads, variables

Solution

Your `anotherThread` simply calls `pthread_cond_wait` without first testing whether the desired condition (counter reaching ten) has already happened. This is incorrect logic, which will lead to the lost wakeup problem: the name of a recurring bug that plagues incorrectly written multithreaded programs.

Condition variables are stateless. If `pthread_cond_signal` or `pthread_cond_broadcast` is called on a condition on which no threads are currently waiting, the operation has no effect. It is not remembered. So it is possible for your signaling thread to count to `10` very quickly, and signal the condition variable, before the other thread has reached the `pthread_cond_wait` call.

You need a loop around `pthread_cond_wait`. The condition must be checked in case it is already true, so that the thread does not wait for a wakeup which already happened. And it should be a loop because wakeups can be spurious: just because the thread falls through the `pthread_cond_wait` doesn't mean that the condition is actually true:

while (cont < 10)
  pthread_cond_wait(&cond, &myMutex);

Also, there is no need to create a thread attribute just to make a thread joinable. This is the default situation when you use a null pointer for the creation attribute. POSIX threads are joinable unless created detached, or converted to detached with `pthread_detach`.

Another thing: whenever possible, avoid calling `pthread_cond_signal` while holding a mutex lock. It's not incorrect, but it's potentially wasteful, because the operation may actually have to call into the OS kernel to wake up a thread, and so you're holding this expensive mutex lock over the entire system call (when all you really need it for is protecting a few machine instructions that working with shared data in your application).

Problem

I wrote a wrote a program and it doesn't work as I expect it to. I have two threads: `thread` triggers `func` and `anotherThread` triggers `anotherFunc`. What I wanted to do is when `cont` reaches value `10` in `func`, `anotherThread` to be triggered using `pthread_cond_wait` and `pthread_cond_signal`. The strange thing is everything works fine if i uncomment the `sleep(1)` line. I'm new to threads and I was following the tutorial here and if I comment the `sleep` line in their example it breaks as well. My question is how can I make this work without any `sleep()` calls? And what happens if in my code both `func` reaches `pthread_mutex_lock` after `anotherFunc`? How can I control these things? This is my code: ``` #include <iostream> #include <stdlib.h> #include <stdio.h> #include <pthread.h> pthread_mutex_t myMutex; pthread_cond_t cond; pthread_attr_t attr; int cont; void *func(void*) { printf("func\n"); for(int i = 0; i < 20; i++) { pthread_mutex_lock(&myMutex); cont++; printf("%d\n", cont); if(cont == 10) { printf("signal:\n"); pthread_cond_signal(&cond); // sleep(1); } pthread_mutex_unlock(&myMutex); } printf("Done func\n"); pthread_exit(NULL); } void *anotherFunc(void*) { printf("anotherFunc\n"); pthread_mutex_lock(&myMutex); printf("waiting...\n"); pthread_cond_wait(&cond, &myMutex); cont += 10; printf("slot\n"); pthread_mutex_unlock(&myMutex); printf("mutex unlocked anotherFunc\n"); printf("Done anotherFunc\n"); pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t thread; pthread_t anotherThread; pthread_attr_init(&attr); pthread_mutex_init(&myMutex, NULL); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_cond_init(&cond, NULL); pthread_create(&anotherThread, &attr, anotherFunc, NULL); pthread_create(&thread, &attr, func, NULL); pthread_join(thread, NULL); pthread_join(anotherThread, NULL); printf("Done MAIN()"); pthread_mutex_destroy(&myMutex); pthread_cond_destroy(&cond); pthread_attr_destroy(&attr); pthread_exit(NULL); return 0; } ``` Sorry for the long post but I'm new to threads and I'm willing to learn. Also do you know some good references or courses/tutorials on threads and networking on Linux? I want to learn create an chat client and I heard that I have to know threads and networking for that. Problem is I don't know pretty good if what I learn is ok since I don't know what I have to know. Thank you so much :)

Original source

Related problems