以下的程式碼哪裡有問題
1 | pthread_mutex_t mutex; |
Spurious wakeup
所謂的Spurious wakeup
就是被Blocking的Thread認為自己滿足條件而被喚醒,而事實上不是這麼一回事。例如
Spurious wakeups may sound strange, but on some multiprocessor systems, making condition wakeup completely predictable might substantially slow all condition variable operations.
由於有Spurious wakeup
的發生,為了程式的正確性,需要為此作處理。
Consumer’s Problem
看上面的
1 | if (q.empty()) |
當Spurious wakeup發生時,這個條件不一定滿足,因此要把if
改成while
,
Producer’s Problem
由於condition variable的signal跟mutex的unlock是獨立事件,因此兩個的順序不重要,正確性都得以保證。不過這樣子的寫法一樣會造成Spurious wakeu
的問題
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
分析如下
- Thread A starts waiting for items to be added to a threadsafe queue.
- Thread B inserts an item on the queue. After unlocking the queue, but before it issues the signal, a context switch occurs.
- Thread C inserts an item on the queue, and issues the cvar signal.
- Thread A wakes up, and processes both items. It then goes back to waiting on the queue.
- Thread B resumes, and signals the cvar.
- Thread A wakes up, then immediately goes back to sleep, because the queue is empty.