Search code examples
clinuxmultithreadingpthreadsthread-synchronization

How to make sure pthread_cond_wait() doesn't miss any pthread_cond_signal()?


I have a Read thread and multiple write threads as the following.

Read thread:

pthread_mutex_lock(mutex);
while(1){
   pthread_cond_wait(cond, mutex);
   switch(state){
   //do something
   }
}
pthread_mutex_unlock(mutex);

Write thread1:

pthread_mutex_lock(mutex);
state = work;
pthread_cond_signal(cond);
//do something
pthread_mutex_unlock(mutex);

Write thread2:

pthread_mutex_lock(mutex);
state = lunch;
pthread_cond_signal(cond);
//do something
pthread_mutex_unlock(mutex);

Assume state is the shared variable and Read thread goes into waiting before all the write threads.

Say the two write threads try to get mutex at the same time and write1 acquires mutex and sends cond. At this point of time both write2 and read threads are locked on the mutex, and so far to my understanding, no thread has a priority to the mutex so we can't be sure when write1 releases the mutex that read thread will acquire it, which will lead to a missed signal and an overwritten state.

I have two questions here:

  1. Is my understanding correct, that the above situation is possible?
  2. If so, how do I make sure that no signal is missed in my code ?

Solution

    1. Is my understanding correct, that the above situation is possible?

    Yes, you are correct.

    1. If so, how do I make sure that no signal is missed in my code.

    If you want to make sure that every change of the variable state is noticed by the "read thread", then you must make sure that no "write thread" changes the variable state until it has been acknowledged by the "read thread". For example, you could make the "read thread" read the value of state and then set that variable to a special value, to indicate to the "writer threads" that state may now be overwritten with a new value.

    However, this means that not only does the "read thread" have to wait for the "writer threads", but the "writer threads" must also wait for the "read thread". This is the producer-consumer problem. A typical solution would be to have two condition variables instead of one:

    • One for the "writer threads" to indicate to the "reader thread" that new data is ready to be read.
    • One for the "reader thread" to indicate to the "writer threads" that new data can now be written.

    In order to minimize threads waiting for each other, you may want to allow for more than one set of data to be stored in your program at once, for example by implementing a queue.