1. 什麼是死鎖 死鎖的處理方法
在並發程序設計中,死鎖 (deadlock) 是一種十分常見的邏輯錯誤。通過採用正確的編程方式,死鎖的發生不難避免。
死鎖的四個必要條件
在計算機專業的本科教材中,通常都會介紹死鎖的四個必要條件。這四個條件缺一不可,或者說只要破壞了其中任何一個條件,死鎖就不可能發生。我們來復習一下,這四個條件是:
•互斥(Mutual exclusion):存在這樣一種資源,它在某個時刻只能被分配給一個執行緒(也稱為線程)使用;
•持有(Hold and wait):當請求的資源已被佔用從而導致執行緒阻塞時,資源佔用者不但無需釋放該資源,而且還可以繼續請求更多資源;
•不可剝奪(No preemption):執行緒獲得到的互斥資源不可被強行剝奪,換句話說,只有資源佔用者自己才能釋放資源;
•環形等待(Circular wait):若干執行緒以不同的次序獲取互斥資源,從而形成環形等待的局面,想像在由多個執行緒組成的環形鏈中,每個執行緒都在等待下一個執行緒釋放它持有的資源。
解除死鎖的必要條件
不難看出,在死鎖的四個必要條件中,第二、三和四項條件比較容易消除。通過引入事務機制,往往可以消除第二、三兩項條件,方法是將所有上鎖操作均作為事務對待,一旦開始上鎖,即確保全部操作均可回退,同時通過鎖管理器檢測死鎖,並剝奪資源(回退事務)。這種做法有時會造成較大開銷,而且也需要對上鎖模式進行較多改動。
消除第四項條件是比較容易且代價較低的辦法。具體來說這種方法約定:上鎖的順序必須一致。具體來說,我們人為地給鎖指定一種類似「水位」的方向性屬性。無論已持有任何鎖,該執行緒所有的上鎖操作,必須按照一致的先後順序從低到高(或從高到低)進行,且在一個系統中,只允許使用一種先後次序。
請注意,放鎖的順序並不會導致死鎖。也就是說,盡管按照 鎖A, 鎖B, 放A, 放B 這樣的順序來進行鎖操作看上去有些怪異,但是只要大家都按先A後B的順序上鎖,便不會導致死鎖。
舉例
假如有三個對象A、B、C,我們人為約定它們的鎖序是: A 先於 B 先於 C。舉例說來,下列鎖序均為合法:
• 鎖C,放C
• 鎖B,放B
• 鎖B,鎖C,放B,放C
• 鎖B,鎖C,放C,放B
• 鎖A,放A
• 鎖A,鎖C,放A,放C
• 鎖A,鎖C,放C,放A
• 鎖A,鎖B,放A,放B
• 鎖A,鎖B,放B,放A
• 鎖A,鎖B,鎖C,放A,放B,放C
• 鎖A,鎖B,鎖C,放C,放B,放A
而在上面定義的系統中,可能導致發生死鎖典型上鎖序列包括:
• 鎖B,鎖A,鎖C,放C,放A,放B
(因為先B後A的上鎖順序違反了鎖序約定,如果另一執行緒同時按照先A後B的順序上鎖,則可能由於執行緒甲獲得了B,執行緒乙獲得了A,而導致雙方同時等待對方釋放所持有的鎖,從而形成死鎖局面;解法是將操作序列中增加適當的鎖操作,即改為鎖B,放B,鎖A,鎖B,鎖C,放C,放A,放B)
或者說,只要拿鎖的時候不出現逆序(例如拿著C的時候試圖抓B或A,或者拿著B的時候試圖抓A),並出現潛在逆序的時候先放掉「小」鎖再抓大的,就一定不造成死鎖了。
2. 處理死鎖的方法
預防死鎖。這是一種較簡單和直觀的預先預防方法。該方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或幾個來預防產生死鎖。預防死鎖是一種易實現的方法,已被廣泛使用。
避免死鎖。同樣是屬於事先預防策略,但它並不是事先採取各種限制措施,去破壞產生死鎖的四個必要條件,而是在資源的動態分配過程中,用某種方法防止系統進入不安全狀態,從而可以避免發生死鎖。
檢測死鎖。這種方法無須事先採取任何限性制措施,允許進程在運行過程中發生死鎖。但可通過檢測機構及時地檢測出死鎖的發生,然後採取適當的措施,把進程從死鎖中解脫出來。
解除死鎖。當檢測到系統中已發生死鎖時,就採取相應的措施,把進程從死鎖中解脫出來。常用的方法是撤消一些進程,回收它們的資源,將資源分配給已處於阻塞狀態的進程,使其能繼續運行。
3. 什麼是死鎖解決死鎖有那幾種策略這些策略分別有哪些實現方法
什麼是死鎖?如果一個進程集合裡面的每個進程都在等待只能由這個集合中的其他一個進程(包括他自身)才能引發的事件,這種情況就是死鎖。這個定義可能有點拗口,一個最簡單的例子就是有資源a和資源b,都是不可剝奪資源,現在進程c已經申請了資源a,進程d也申請了資源b,進程c接下來的操作需要用到資源b,而進程d恰好也在申請資源a,那麼就引發了死鎖。這個肯定每個人都看過了。然後套用回去定義:如果一個進程集合裡面(進程c和進程d)的每個進程(進程c和進程d)都在等待只能由這個集合中的其他一個進程(對於進程c,他在等進程d;對於進程d,他在等進程c)才能引發的事件(釋放相應資源)。這里的資源包括了軟的資源(代碼塊)和硬的資源(例如掃描儀)。資源一般可以分兩種:可剝奪資源(preemptable)和不可剝奪資源(nonpreemptable)。一般來說對於由可剝奪資源引起的死鎖可以由系統的重新分配資源來解決,所以一般來說大家說的死鎖都是由於不可剝奪資源所引起的。死鎖的四個必要條件互斥條件(mutual
exclusion):資源不能被共享,只能由一個進程使用。
請求與保持條件(hold
and
wait):已經得到資源的進程可以再次申請新的資源。
非剝奪條件(no
pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
2.檢測死鎖並且恢復。
3.仔細地對資源進行動態分配,以避免死鎖。
4.通過破除死鎖四個必要條件之一,來防止死鎖產生。
4. 操作系統的選擇題答案
30.等待當前磁軌上的某指定扇區旋轉到磁頭下所需的時間稱為( A )
A.尋找時間 B.啟動時間
C.延遲時間 D.傳送時間
31.作業調度選中一個作業並把它裝入主存,就為該作業創建一個進程,這個進程的初始狀態為( D )
A.收容狀態 B.就緒狀態
C.執行狀態 D.等待狀態
32.能使平均周轉時間最小的作業調度演算法是( B )
A.計算時間短的作業優先演算法 B.響應比最高者優先演算法
C.優先數調度演算法 D.均衡調度演算法
33.引起一個進程從運行狀態變為等待狀態的原因可能是由於( A )
A.有更高優先順序的進程就緒 B.某外圍設備完成了指定的操作
C.進程調用了P操作 D.進程調用了V操作
34.在實現進程通信時會導致調用Send原語的進程被設置成「等信箱」狀態的原因是
( D )
A.指定的信箱不存在 B.調用時沒有設置參數
C.指定的信箱中無信件 D.指定的信箱中存滿了信件
35.對資源採用按序分配的策略可以使產生死鎖的______條件不成立。( D )
A.互斥使用資源 B.佔有並等待資源
C.不可搶奪資源 D.循環等待資源
36.在下列解決死鎖的方法中,屬於死鎖預防策略的是( A )
A.銀行家演算法 B.資源有序分配法
C.定時運行死鎖檢測程序法 D.資源分配圖化簡法
37.要求進程一次性申請所需的全部資源,是破壞了死鎖必要條件中的( D )
A.互斥 B.請求與保持 C.不剝奪 D.循環等待
38.使用一個信號量協調6個進程對2個同類臨界資源的訪問,下列哪個信號量值不應該出現( A )
A.3 B.0 C.–1 D.–3
39.可執行程序存在於( C )
A.名空間 B.邏輯地址空間
C.儲存空間 D.物理地址空間
40.從下列關於虛擬存儲器的論述中,選出一條正確的論述。B
A.要求作業運行前,必須全部裝入內存,且在運行中必須常駐內存;
B.要求作業運行前,不必全部裝入內存,且在運行中不必常駐內存;
C.要求作業運行前,不必全部裝入內存,但在運行中必須常駐內存;
D.要求作業運行前,不必全部裝入內存,但在運行中必須常駐內存;
41.可解決文件重名問題的最簡單的目錄結構是( B )
A.單級目錄 B.樹型結構目錄 C.二級目錄 D.便於共享的目錄
42.系統利用 SPOOLING技術實現(D )
A.對換手段 B.虛擬設備 C.系統調用 D.虛擬存儲
5. 死鎖定理是用於處理死鎖的哪一種方法
死鎖定理用於檢測死鎖。
系統處於死鎖的充分條件是:當且僅當此狀態的進程-資源分配圖(是對當前狀態的圖形化描述)是不可完全簡化的,這一充分條件稱為死鎖定理。由定理可知,這是一種檢測方法。
6. 構成死鎖的必要條件是什麼如何檢測死鎖,解除死鎖
死鎖的四個必要條件
操作系統中有若干進程並發執行,它們不斷申請、使用、釋放系統資源,雖然系統的進
程協調、通信機構會對它們進行控制,但也可能出現若干進程都相互等待對方釋放資源才能
繼續運行,否則就阻塞的情況。此時,若不藉助外界因素,誰也不能釋放資源,誰也不能解
地等待永遠不會發生的條件,系統處於停滯狀態,這就是死鎖。
產生死鎖的原因主要是:
(1) 因為系統資源不足。
(2) 進程運行推進的順序不合適。
(3) 資源分配不當等。
如果系統資源充足,進程的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則
就會因爭奪有限的資源而陷入死鎖。其次,進程運行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之
一不滿足,就不會發生死鎖。
死鎖的解除與預防:
理解了死鎖的原因,尤其是產生死鎖的四個必要條件,就可以最大可能地避免、預防和
定資源的合理分配演算法,避免進程永久占據系統資源。此外,也要防止進程在處於等待狀態
的情況下佔用資源。因此,對資源的分配要給予合理的規劃。
7. 如何檢測死鎖並快速定位死鎖位置
自動檢測死鎖的功能,如果發生死鎖,會馬上列印堆棧信息,並終止程序,如果是在調試環境中,會自動斷點到發生死鎖的地方。
實現思路如下:
比如Task A已經擁有了Lock 1,並准備去獲取Lock 2,此時檢測一下Lock 2是否被其它Task擁有了,如果沒有,那Task A就很Happy的直接獲取Lock 2就行了。如果Lock 2已經被Task B擁有了,那就檢測一下Task B是否在等待Lock 1,如果是的話就說明是死鎖了,此時列印一下堆棧信息,如果在調試環境,就中斷調試,以方便查看死鎖現場,否則直接退出程序。
這樣雖然上鎖的效率會降低,但很快就能發現死鎖。一般發布游戲到線上的時候,就把死鎖檢測功能去掉,也不會影響性能。
看下我的測試代碼:
TaskMutex mutex1;
TaskMutex mutex2;
void m1() {
try {
mutex1.lock();
sleep(1);
mutex2.lock();
mutex2.unlock();
mutex1.unlock();
} catch (...) {
std::cout << boost::current_exception_diagnostic_information() << std::endl;
}
}
void m2() {
try {
mutex2.lock();
sleep(1);
mutex1.lock();
mutex2.unlock();
mutex1.unlock();
} catch (...) {
std::cout << boost::current_exception_diagnostic_information() << std::endl;
}
}
int main(int argc, char *argv[]) {
try {
IoScheler scheler(2);
scheler.schele(boost::bind(&m1));
scheler.schele(boost::bind(&m2));
scheler.stop();
} catch (...) {
std::cout << boost::current_exception_diagnostic_information() << std::endl;
}
std::cout << "will exit.." << std::endl;
return 0;
}
8. 如何檢查oracle死鎖
oracle死鎖問題一直困擾著我們,下面就教您一個oracle死鎖的檢查方法,如果您之前遇到過oracle死鎖方面的問題,不妨一看。 一、資料庫死鎖的現象 程序在執行的過程中,點擊確定或保存按鈕,程序沒有響應,也沒有出現報錯。 二、oracle死鎖的原理 當對於資料庫某個表的某一列做更新或刪除等操作,執行完畢後該條語句不提交,另一條對於這一列數據做更新操作的語句在執行的時候就會處於等待狀態,此時的現象是這條語句一直在執行,但一直沒有執行成功,也沒有報錯。 三、oracle死鎖的定位方法 通過檢查資料庫表,能夠檢查出是哪一條語句被死鎖,產生死鎖的機器是哪一台。 1)用dba用戶執行以下語句 以下是代碼片段: select username,lockwait,status,machine,program from v$session where sid in (select session_id from v$locked_object) 如果有輸出的結果,則說明有死鎖,且能看到死鎖的機器是哪一台。欄位說明: Username:死鎖語句所用的資料庫用戶; Lockwait:死鎖的狀態,如果有內容表示被死鎖。 Status: 狀態,active表示被死鎖 Machine: 死鎖語句所在的機器。 Program: 產生死鎖的語句主要來自哪個應用程序。 2)用dba用戶執行以下語句,可以查看到被死鎖的語句。 以下是代碼片段:
9. 以下關於死鎖問題的說法中正確的是
第四個正確
10. 死鎖產生的4個必要條件,如何檢測,解除死鎖
死鎖的四個必要條件
操作系統中有若干進程並發執行,它們不斷申請、使用、釋放系統資源,雖然系統的進
程協調、通信機構會對它們進行控制,但也可能出現若干進程都相互等待對方釋放資源才能
繼續運行,否則就阻塞的情況。此時,若不藉助外界因素,誰也不能釋放資源,誰也不能解
地等待永遠不會發生的條件,系統處於停滯狀態,這就是死鎖。
產生死鎖的原因主要是:
(1)
因為系統資源不足。
(2)
進程運行推進的順序不合適。
(3)
資源分配不當等。
如果系統資源充足,進程的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則
就會因爭奪有限的資源而陷入死鎖。其次,進程運行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件:
(1)
互斥條件:一個資源每次只能被一個進程使用。
(2)
請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3)
不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4)
循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之
一不滿足,就不會發生死鎖。
死鎖的解除與預防:
理解了死鎖的原因,尤其是產生死鎖的四個必要條件,就可以最大可能地避免、預防和
定資源的合理分配演算法,避免進程永久占據系統資源。此外,也要防止進程在處於等待狀態
的情況下佔用資源。因此,對資源的分配要給予合理的規劃。