3 回答

TA貢獻2016條經驗 獲得超9個贊
如果不將互斥鎖鎖定在更改條件和信號的代碼路徑中,則可能會丟失喚醒。考慮這對過程:
流程A:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
進程B(不正確):
condition = TRUE;
pthread_cond_signal(&cond);
然后考慮這種可能的指令交織,condition開始于FALSE:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
現在condition是TRUE,但是進程A滯留在條件變量上等待-它錯過了喚醒信號。如果我們更改進程B來鎖定互斥鎖:
進程B(正確):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...那么上述情況就不會發生;喚醒將永遠不會被錯過。
(請注意,您實際上可以將pthread_cond_signal()自身移動到之后pthread_mutex_unlock(),但是這可能導致線程的最佳調度不太理想,并且由于更改了條件本身,您已經鎖定了該代碼路徑中的互斥鎖)。

TA貢獻1993條經驗 獲得超6個贊
根據本手冊:
該pthread_cond_broadcast()或 pthread_cond_signal()功能 可以由一個線程是當前是否擁有互斥體被稱為該線程調用pthread_cond_wait() 或pthread_cond_timedwait()已與在他們等待的條件變量相關聯; 但是,如果需要可預測的調度行為,則該互斥鎖應由線程調用pthread_cond_broadcast()或 鎖定 pthread_cond_signal()。
可預測的調度行為語句的含義由comp.programming.threads上的Dave Butenhof(使用POSIX線程編程的作者)解釋了,并在此處提供。

TA貢獻1998條經驗 獲得超6個贊
caf,在示例代碼中,流程B進行了修改,condition而沒有先鎖定互斥鎖。如果進程B在修改過程中只是簡單地鎖定了互斥鎖,然后在調用之前仍然解鎖了互斥鎖pthread_cond_signal,那將沒有問題---我是否正確?
我直覺上相信caf的位置是正確的:pthread_cond_signal不擁有互斥鎖就打電話是個壞主意。但是,caf的榜樣實際上并不是支持這一立場的證據。僅是證明弱點(實際上是不言而喻)的證據,除非您先鎖定了該互斥鎖,否則修改由互斥鎖保護的共享狀態是一個壞主意。
誰能提供一些示例代碼,其中調用pthread_cond_signal后pthread_mutex_unlock產生正確的行為,但調用pthread_mutex_unlock后pthread_cond_signal產生錯誤的行為?
- 3 回答
- 0 關注
- 1533 瀏覽
添加回答
舉報