
240
|
第七章
避免死結
避免死結很重要,而且唯一安全一致的辦法,是從一開始就把上鎖機制設計到你的多執
行緒化程式。關鍵在於排他鎖要關聯到資料(而非程式碼),而且要有清楚的資料(以
及排他鎖)層級。例如,死結的一個簡單的形式稱為 ABBA 死結或稱
致命擁抱
(
deadly
embrace
)。如果一個執行緒取得排他鎖 A 之後又要取得排他鎖 B,而另一個執行緒取得
排他鎖 B 之後又要取得排他鎖 A(因此是 ABBA),便會發生此情況。若時序正確,這
兩個執行緒都會成功取得它們的頭一個排他鎖:執行緒 1 持有排他鎖 A,而執行緒 2 持
有排他鎖 B。當它們接著去取得其他的排他鎖時,它們會發現該排他鎖已被其他的執行
緒持有,因此它們都會受到阻擋,直到排他鎖被釋出。因為每個持有排他鎖的執行緒也
都在等待對方的排他鎖,所以排他鎖不會被釋出,導致執行緒發生死結。
修正此問題需要明確的規則:取得排他鎖 B 之前必須先取得排他鎖 A。隨著你的程式變
得複雜,它的同步化也會因而變得複雜,導致這些規則的實施變得更為困難。設計程式
的時候需要早點開始加入這些明確的規則。
Pthread
Linux 核心對執行緒的支援僅提供了底層的基礎呼叫,例如
clone()
系統呼叫。任何的執
行緒程式庫有大部分位於用戶空間。許多大型軟體專案都會定義自己的執行緒程式庫:
例如,Android、Apache、GNOME 及 Mozilla 都有提供它們自己的執行緒程式庫;此
外,一些程式語言,像是 C++11 及 Java,也會為執行緒提供標準程式庫的支援 ...