鐵則4: 請不要做執行緒的非同步撤消的設計在pthread的規格說明中,允許乙個執行緒可以強制中斷某個執行緒的執行。這就是所說的非同步撤消。咋一看還是挺簡單的。但是搞不好可能會引起各種各樣的問題。請不要在不能把握問題的實質就做出使用執行緒的非同步撤消的設計!
執行緒的撤消有下面的兩種方式。
方式2: 延遲撤銷(pthread_cancel_deferred)
還有,到底是用哪種撤消方式,不是撤消側,而是被撤銷側能夠決定的*1
。另外,在被撤銷側也能夠選擇完全禁止撤消的這種方式 *2
。會造成什麼問題呢
那麼,讓我看看亂用執行緒的非同步撤消會引起什麼問題呢。看過準則3的人可能會知道,在下面的指令碼裡,被撤銷執行緒以外的任意乙個執行緒會被死鎖。
執行緒1中呼叫malloc函式正在做記憶體分配的過程中,執行緒2非同步撤消了執行緒1的處理在這個例子中使用了malloc函式,但是其他的危險函式還有很多。執行緒1馬上被撤銷,但是malloc函式中的互斥鎖就沒有執行緒去解除了
後面的任意乙個執行緒如果再次呼叫malloc函式的話就會馬上導致該執行緒死鎖
反之,即使做了非同步撤消也沒有問題的函式也有少數存在的、我們把它們叫做「async-cancel safe函式」或者「非同步撤消安全函式」。在一些商用unix*3
中、os提供的api函式的文件說明中有async-cancel safety的記載、但是在linux(glibc)裡就很遺憾,幾乎沒有相關的說明。
在這兒,參看規格(susv3)的話,會發現,、描述非同步撤消安全的函式只有3個。
pthread_cancel
pthread_setcancelstate
pthread_setcanceltype
而且、裡面還有"no other functions are required to be async-cancel-safe"這樣的記載。因此,linux的場合,如果在文件裡沒有記載成async-cancel safety的函式,我們還是把它假定成不安全的函式為好!
如何避免這些問題呢
在多執行緒程式設計中為了安全的使用非同步撤消處理、有沒有迴避死鎖的方法呢?我們試著想了幾個。他們與準則3裡的執行緒+fork的場合的迴避策很相似。
迴避方法1: 被撤銷執行緒中,只能使用非同步撤消安全函式
首先,被撤銷執行緒中,只能使用非同步撤消安全函式。但是這個方法
中有以上的兩點,所以這個迴避方法幾乎不現實。
迴避方法2: 被撤銷執行緒中,在做非非同步撤消安全處理的過程中,再把撤消方式設定成「延遲」或者是「禁止」
第二個是,被撤銷執行緒在做非非同步撤消安全處理的過程中,把撤消方式再設定成「延遲」或者「禁止」。對於這個方法
有上面樣的問題、會導致「一精心設計撤消方式的替換,從一開始就使用延遲撤消還不夠好」這樣的結果。所以這幾乎是不好的乙個迴避策。
迴避方法3: 使用pthread_cleanup_push函式,登入非同步撤消時的執行緒資料清除的**函式
第三種則是,用pthread_cleanup_push函式、登入乙個在非同步撤消發生時的資料清除的**函式。這和在準則3中介紹的pthread_atfork函式有點兒類似。用這個函式登入的**函式來清除執行緒的資料和鎖,就可以迴避死鎖了。
...但是,pthread_cleanup_push函式登入的**函式,在「延遲撤消」的場合是不能被呼叫的。因此、這個迴避方法對於非同步撤消沒有什麼大的作用。
迴避方法4: 不要執行非同步撤消處理
最後是、不要執行非同步撤消處理。反而代之的是、 或者
這是比較實際的做法,是我們值得推薦的。
*1:pthread_setcanceltype函式
*2:pthread_setcancelstate函式
*3:solaris和hp-ux等 編輯
收藏引用 所屬分類: c++ 、c 、unix/linux
請不要做浮躁的人
請不要做浮躁的人 2.初學者請不要看太多太多的書那會誤人子弟的,先找本系統的學,很多人用了很久都是只對部分功能熟悉而已,不系統還是不夠的。3.看幫助,不要因為很難而自己是初學者所以就不看 幫助永遠是最好的參考手冊,雖然幫助的文字有時候很難看懂,總覺得不夠直觀。4.不要被物件 屬 方法等詞彙所迷惑 最...
請不要做浮躁的人
請不要做浮躁的人 2.初學者請不要看太多太多的書那會誤人子弟的,先找本系統的學,很多人用了很久都是只對部分功能熟悉而已,不系統還是不夠的。3.看幫助,不要因為很難而自己是初學者所以就不看 幫助永遠是最好的參考手冊,雖然幫助的文字有時候很難看懂,總覺得不夠直觀。4.不要被物件 屬性 方法等詞彙所迷惑 ...
請不要做浮躁的人!
請不要做浮躁的人!轉貼 請不要做浮躁的人!bbs 水木清華站,作者做了部分內容新增 2.初學者請不要看太多太多的書那會誤人子弟的,先找本系統的學,很多人用了很久 都是只對部分功能熟悉而已,不系統還是不夠的。3.看幫助,不要因為很難而自己是初學者所以就不看 幫助永遠是最好的參考手冊,雖然幫助的文字有時...