以下的程式碼哪裡有問題
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.