When writing a synchronization queue, it is useful to condition variables to synchronize the threads of the operations queue. When the queue is empty, the get thread is allowed to hang until the add thread adds elements to the queue and by waking the condition variable, the get thread continues to run down. Conditional variables are used in multithreaded programs to implement the common method of "wait-and-wake" logic. The condition variable is coupled to the mutex to avoid conditional competition: A thread prepares to wait for a condition variable, and the other thread triggers the condition exactly before it enters the wait. When you use conditional variables for synchronization, you typically encode them in the following way:
1 pthread_mutex_t Mutex;2 pthread_cond_t cond;3 4 //Get Thread5 intGet ()6 {7Pthread_mutex_lock (&mutex);8 while(Queue.empty ())9 {TenPthread_cond_wait (&cond, &mutex); One } Aitem =Queue.front (); -Pthread_mutex_unlock (&mutex); - returnitem; the } - //Add Thread - voidADD (intItem) - { +Pthread_mutex_lock (&mutex); - Queue.push (item); +Pthread_cond_signal (&cond); APthread_mutex_unlock (&mutex); at}
I wonder if you have noticed the order of LINE21 and Line22,pthread_cond_signal and Pthread_mutex_unlock in the Add function, that is, whether the order of wake and unlock is affecting the operation of the program. In this simple analysis, we know that after the add thread adds an element to the queue, it calls Pthread_cond_signal, and the thread that blocks the get operation wakes up, and the thread that is blocking at pthread_cond_wait () wakes up. And to return, it is important to note that not after the add thread calls the Pthread_cond_signal function,pthread_cond_wait () returns immediately , but it acquires the mutex and re-lock in order to return to execution. According to the analysis, the conclusion is that if the signal is first unlock, then the thread that is currently blocked on pthread_cond_wait may get to the mutex immediately (because there may be other add threads blocking on the mutex, so it does not necessarily acquire the mutex), Re-lock, return and execute down, and if unlock signal, then the mutex may have been acquired by other threads, then signal wake Pthread_cond_wait will continue to wait for the mutex to be fetched away from the thread release, May wait longer than the previous case, and the other add thread wakes it up. Not sure whether the analysis is correct, so on the stack overflow see the same problem, it is recommended to put signal before unlock, some translation summarized as follows:
If the Add function will unlock before, signal may produce spurious wakeups, consider the following scenario:
1. Thread A blocks the Get function, unlocks, waits for the add operation to add item to the queue.
2. Thread B calls the Add function to add item to the queue. After the Add function unlock, a context switch was sent before signal.
3. Thread C gets to the mutex, calls the Add function, adds item to the queue, unlocks and calls the signal function.
4. At this point, thread A gets the Mutex,wait function returned, processing the two item that was just added, and then continues to block on the condition variable.
5. At this point, if thread B gets the CPU time slice, then continue running from 2, call signal, wake up a thread
6. Thread A is awakened, but because the previous item has been get out, the queue is still empty, so thread A is in a blocking state again.
Reference:
Http://stackoverflow.com/questions/6312342/pthread-cond-wait-and-mutex-requirement
Http://stackoverflow.com/questions/1640389/pthreads-pthread-cond-signal-from-within-critical-section
Http://stackoverflow.com/questions/6419117/signal-and-unlock-order
The order of conditional variables signal and unlock