簡體   English   中英

當pthread在等待互斥鎖時死機會發生什么?

[英]What happens when a pthread dies while waiting on a mutex?

如果一個進程有三個線程,T1,T2和T3,並且所有三個線程都嘗試獲取對互斥鎖M1的鎖定,我理解一個將獲取互斥鎖,另外兩個將等到它們獲取互斥鎖。

如果我使用pthread_mutexattr_setrobust()來使線程健壯,那么我理解如果T1保持M1,並且T1在釋放之前終止,則M1,T2被喚醒並返回值為EOWNERDEAD。 T2然后可以清理受保護資源的狀態。

現在,如果T1擁有M1而T2和T3在M1上等待,會發生什么。 T2終止。 怎么了? 當T1釋放M1時,互斥鎖是否直接進入T3? T3是否獲得了EOWNERDEAD,或者它只是看向T3,就像從未發生任何事情那樣,並且不需要清理? 似乎T3應該只采用M1,因為T2無法使線程進入不一致狀態。 任何答案? 這是一個讓我感興趣的問題,而不是試圖解決一個特定的問題,所以我們將不勝感激。

編輯:我不是想弄清楚如何正確地做,而是我試圖找出發生了什么,一般來說對於pthread實現,當T2被終止或被取消時(對這兩種情況感興趣,並且只是開始理解它可能對結果產生的差異)。 它是否定義了行為?

我的目標平台是使用Windows Services for Unix的Windows,以防它依賴於平台,但我對應該發生的事情感興趣。 https://technet.microsoft.com/en-us/library/bb463209.aspx

注意:我的答案完全基於所寫的標准,而不是基於個人經驗或相關專業知識。

取消pthread分為兩種情況:

如果pthread配置為延遲取消(這是默認值),那么根據標准的文字讀數,直到聲明互斥鎖(或未能聲明)之后才會處理取消請求,因為pthread_mutex_lock和朋友是不在可取消的功能列表中,如標准2.9.5節所示。

我不確定各種實現是否實際上以這種方式運行,因為它似乎是不合需要的。 如果實現確實允許在嘗試聲明互斥鎖時取消(可能是因為pthread_mutex_lock函數在內部使用了列出的可取消函數之一),我希望它會導致互斥鎖保持一致且無人問津,但是符合Jille的答案,但標准似乎沒有明確要求它。

如果pthread配置為異步取消,則行為未定義:

pthread_cancel(),pthread_setcancelstate()和pthread_setcanceltype()函數被定義為async-cancel safe。

本卷POSIX.1-2008中的其他功能都不需要async-cancel-safe。

如果線程啟用了異步取消並在執行非async-cancel-safe的函數期間取消,則行為未定義。

似乎不可能終止單個pthread。 第2.4.3節:

當信號傳遞給線程時,如果該信號的動作指定終止,停止或繼續,則應分別終止,停止或繼續整個過程。

根據POSIX.1-2008tc1的pthread_mutex_lock()規范:

  • 如果pthread_mutex_lock()返回零或[EOWNERDEAD]則線程將成為互斥鎖的所有者。
  • 當擁有互斥鎖時,包含擁有線程(或者,可選地,擁有線程)的進程終止時,會發生錯誤[EOWNERDEAD]

在您的示例中, pthread_mutex_lock()對於T2不成功,因此T3將無錯誤地獲取M1。

您必須使用條件變量才能使其完美地工作。 我復制粘貼下面的一些文檔。

條件變量允許線程同步到共享資源的值。 通常,條件變量用作線程之間的通知系統。

例如,你可以有一個計數器,一旦達到某個計數,你想要一個線程激活。 一旦計數器達到限制就激活的線程(或多個線程)將等待條件變量。 活動線程在此條件變量上發出信號,以通知在此條件變量上等待/休眠的其他線程; 從而導致等待線程被喚醒。 如果要通知等待條件變量的所有線程進行喚醒,也可以使用廣播機制。 從概念上講,這是通過右側帶有偽代碼的圖形建模的。

在等待條件變量時,等待應該在循環內,而不是在簡單的if語句中,因為虛假的喚醒。 如果線程被喚醒,則無法保證,這是信號或廣播呼叫的結果。

文檔鏈接: http//randu.org/tutorials/threads/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM