3 回答

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

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

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