(数据库系统概论|王珊)第十一章并发控制-第二、三、四节:封锁、封锁协议活锁和死锁
文章目錄
- 一:封鎖
- (1)概念
- (2)類型
- (3)控制方式
- 二:封鎖協議
- (1)概念
- (2)三級封鎖協議
- ①:一級封鎖協議
- ②:二級封鎖協議
- ③:三級封鎖協議
- 三:活鎖和死鎖
- (1)活鎖
- (2)死鎖
- A:概念
- B:死鎖產生的四個必要條件
- ①:互斥條件
- ②:不可剝奪條件
- ③:持有并等待條件
- ④:循環等待條件
- C:解決死鎖的方法
- 預防死鎖
- ①:破壞互斥條件
- ②:破壞不可剝奪條件
- ③:破壞持有并等待條件(對應一次封鎖法)
- ④:破壞循環等待條件(對應順序封鎖法)
- 死鎖檢測
- ①:超時法
- ②:等待圖法(資源分配圖)
- 死鎖解除
一:封鎖
(1)概念
封鎖:封鎖就是事務TTT在對某個數據對象(表、記錄等)操作之前,先向系統發出請求,對其加鎖;加鎖后事務TTT對該數據對象就有了一定的控制,在事務TTT釋放它的鎖之前,其它的事務不能更新此數據對象;DBMS通常提供了多種類型的封鎖,一個事務對某個數據對象加鎖后究竟擁有怎樣的控制是由封鎖的類型決定的
(2)類型
基本封鎖類型有如下兩種
- 排他鎖(XXX鎖):又稱為寫鎖,若事務TTT對數據對象AAA加上XXX鎖,則只允許TTT讀取和修改AAA,其他任何事務都不能再對AAA加任何類型的鎖,直到TTT釋放AAA上的鎖
- 共享鎖(SSS鎖):又稱為讀鎖,若事務TTT對數據對象AAA加上SSS鎖,則其他事務只能再對AAA加SSS鎖,而不能加XXX鎖,直到TTT釋放AAA上的SSS鎖
,
(3)控制方式
排他鎖與共享鎖的控制方式可以用下圖所示的相容矩陣來表示
- 最左邊一列表示事務T1T_{1}T1?已經獲得的數據對象上的鎖的類型,其中橫線表示沒有加鎖
- 最上面一行表示另一事務T2T_{2}T2?對同一數據對象發出的封鎖請求
- T2T_{2}T2?的封鎖請求能否被滿足用矩陣中的YYY和NNN表示。其中YYY表示事務T2T_{2}T2?的封鎖與T1T_{1}T1?已持有的鎖相容,封鎖請求可以滿足;NNN表示T2T_{2}T2?的封鎖請求與T1T_{1}T1?已持有的鎖沖突,請求被拒絕
二:封鎖協議
(1)概念
封鎖協議:是指在運用XXX鎖和SSS鎖對數據對象加鎖時需要遵照的一些規則。例如,何時申請、持續時間、和何時釋放等。不同的封鎖協議,為并發操作的正確調度提供了一定的保證,所能達到的系統一致性級別也是不同的。常用的封鎖協議有
- 支持一致性維護的三級封鎖協議(本節)
- 支持并行調度可串行化的兩段鎖協議/避免死鎖的協議
(2)三級封鎖協議
①:一級封鎖協議
一級封鎖協議:事務TTT在修改數據RRR之前必須先對其加XXX鎖,直到事務結束(COMMIT或ROLLBACK)才釋放
- 優點:可以防止丟失修改
- 缺點:如果僅是讀數據,是不需要加鎖的。所以它不能保證可重復讀和不讀臟數據
②:二級封鎖協議
二級封鎖協議:是指在一級封鎖協議基礎上增加事務TTT在讀取數據RRR之前必須先對其加SSS鎖,讀完后即可釋放SSS鎖
- 優點:可以方式丟失修改和讀臟數據
- 缺點:不能保證可重復讀
③:三級封鎖協議
三級封鎖協議:是指在一級封鎖協議基礎上增加事務TTT在讀取數據RRR之前必須先對其加SSS鎖,直到事務結束才可以釋放SSS鎖
- 防止丟失修改和讀臟數據,還防止了不可重復讀
總結
三:活鎖和死鎖
一個問題的解決必然會導致另一個問題的出現。封鎖技術可以有效地解決并發操作的一致性問題,但是會帶來新的問題
- 活鎖
- 死鎖
(1)活鎖
活鎖:事務T1T_{1}T1?封鎖數據RRR,事務T2T_{2}T2?又請求封鎖RRR,因此事務T2T_{2}T2?被迫等待。此時,事務T3T_{3}T3?也請求封鎖RRR,因此事務T3T_{3}T3?也被迫等待。當T1T_{1}T1?釋放RRR的封鎖后,系統卻首先批準了T3T_{3}T3?的請求,T2T_{2}T2?只能繼續等待。然后,又有別的事務到來,由于事務T2T_{2}T2?的優先級可能較低,所以導致它長時間得不到服務,產生饑餓現象。這就是活鎖。避免活鎖可以廢除特權,采用先來先服務算法
(2)死鎖
- 注意此部分在操作系統中屬于重點內容,詳細了解請點擊跳轉:【專欄必讀】王道考研408操作系統萬字筆記(從學生角度輔助大家理解):各章節導航及思維導圖
A:概念
死鎖:兩個或兩個以上事務均處于等待狀態,每個事務都在等待其中另一個事務封鎖的數據,導致任何事務都不能向前推進的現象
B:死鎖產生的四個必要條件
- 此部分內容選自:(王道408考研操作系統)第二章進程管理-第四節1:死鎖相關概念
①:互斥條件
互斥條件:是指只有對必須互斥使用的資源搶奪時才可能導致死鎖。比如打印機設備就可能導致互斥,但是像內存、揚聲器則不會
- 進程A已經獲得資源,進程B只能等待
②:不可剝奪條件
不可剝奪條件:是指進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放
③:持有并等待條件
持有并等待條件:是指進程已經至少保持了一個資源,但又提出了新的資源請求,但是該資源又被其他進程占有,此時請求進程被阻塞,但是對自己持有的資源保持不放
④:循環等待條件
循環剝奪條件:是指存在一種進程資源的循環等待鏈,鏈中的每一個進程已獲得的資源同時被下一個進程所請求
C:解決死鎖的方法
解決死鎖主要有下面三種方法(每一種在對應文章中都有詳細介紹,限于篇幅,這里只挑取重點)
- (王道408考研操作系統)第二章進程管理-第四節2:死鎖處理策略之預防死鎖
- (王道408考研操作系統)第二章進程管理-第四節2:死鎖處理策略之避免死鎖(銀行家算法)
- (王道408考研操作系統)第二章進程管理-第四節3:死鎖處理策略之檢測和解除
預防死鎖
①:破壞互斥條件
- 互斥條件是指只有對必須互斥使用的資源搶奪時才可能導致死鎖。比如打印機設備就可能導致互斥,但是像內存、揚聲器則不會
破壞互斥條件:如果把只能互斥使用的資源改造為允許共享使用,則系統不會進入死鎖狀態。但并不是所有資源都可以改造為成共享使用的資源的,而且為了系統安全性,很多地方也是禁止改造的,所以互斥條件一般無法破壞
②:破壞不可剝奪條件
- 不可剝奪條件是指進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放
破壞不可剝奪條件:可以有以下兩種方案
- 方案一:當某個進程請求新的資源得不到滿足時,它必須立即釋放保持的所有資源,待以后需要時再重新申請。 也就是說,即使某些資源尚未使用完,也需要主動釋放
- 方案二:當某個進程需要的資源被其他進程占有的時候,可以由操作系統協助,將想要的資源強行剝奪。 這種方式一般需要考慮各個進程的優先級
缺點
- 實現起來比較復雜
- 釋放已獲得的資源可能造成前一階段工作的失效,所以這種方法一般只適用于易保存和恢復狀態的資源,比如CPU
- 反復申請和釋放資源會增加系統開銷,降低系統吞吐量
- 若采用方法一,意味著只要暫時得不到某個資源,之前獲得的那些資源都需要放棄,以后再重新申請,容易導致進程饑餓
③:破壞持有并等待條件(對應一次封鎖法)
- 持有并等待條件:是指進程已經至少保持了一個資源,但又提出了新的資源請求,但是該資源又被其他進程占有,此時請求進程被阻塞,但是對自己持有的資源保持不放
破壞持有并等待條件:可以采用靜態分配方法。進程在運行前一次申請完它所需要的全部資源,在它的資源未得到滿足前,不允許投入運行;一旦投入運行,這些資源就一直歸它所有,該進程不會再請求別的任何資源
缺點
- 有些資源可能只需要使用很短的時間,因此如果進程的整個運行期間都一直保持著所有資源,就會造成嚴重的資源浪費,資源利用率極低,并且該策略也有可能導致饑餓現象
④:破壞循環等待條件(對應順序封鎖法)
- 循環剝奪條件:是指存在一種進程資源的循環等待鏈,鏈中的每一個進程已獲得的資源同時被下一個進程所請求
破壞循環等待條件:可以采用順序資源分配方法。首先給系統中的資源進行編號,規定每個進程必須按照編號遞增的順序請求資源,編號相同的資源(也就是同類資源)一次申請完
- 這是因為一個進程只有在已經占有小編號資源的同時,才有資格申請更大編號的資源。所以已經持有大編號資源的進程不可能逆向申請小編號的資源
缺點
- 不方便增加新的設備,因為可能需要重新分配所有的編號
- 進程實際使用資源的順序可能和編號遞增順序不一致,造成資源浪費
- 必須按規定次序申請資源,為用戶編程帶來了麻煩
死鎖檢測
①:超時法
超時法:如果一個事務的等待時間超過了規定的時限,就認為發生了死鎖
- 優點:實現簡單
- 缺點:有可能誤判死鎖;時限標準難以把握
②:等待圖法(資源分配圖)
兩種結點
- 進程結點:對應一個進程
- 資源結點:對應一類資源,其數量可能有多個
兩種邊
- 進程結點->資源結點:進程想要申請多少個資源,每條邊代表一個
- 資源結點->進程結點:表示已經為進程分配了多少個資源,每條邊代表一個
- 進程P1P_{1}P1?已經分得了兩個R1R_{1}R1?資源,又在請求一個R2R_{2}R2?資源;
- 進程P2P_{2}P2?已經分得了一個R1R_{1}R1?資源和一個R2R_{2}R2?資源,又在請求一個R1R_{1}R1?資源;
判斷是否發生死鎖:如果系統中的可用資源數目滿足進程的需求,那么這個進程暫時是不會被阻塞的,可以順利執行;如果這個進程結束后將資源歸還給了系統,就可能使某些正在等待資源的進程被激活,并順利執行下去
比如下圖中:R2R_{2}R2?資源的數目共有2個,其中一個分配給了P2P_{2}P2?,此時P1P_{1}P1?請求一個,而可用資源數目夠,因此P1P_{1}P1?不會被阻塞;
R1R_{1}R1?資源的數目共有3個,其中2個分配給了P1P_{1}P1?,一個分配給了P2P_{2}P2?,所以P2P_{2}P2?的請求不能滿足,而P1P_{1}P1?是可以順利執行的,所以P2P_{2}P2?在等待P1P_{1}P1?執行完畢并歸還資源后,便可以順利執行下去
P1P_{1}P1?結束之后,歸還資源,并且它再不會請求任何資源,因此取出和P1P_{1}P1?相連的邊
P2P_{2}P2?在結束之后也會歸還資源
可完全簡化:按照上述過程,如果能夠消除所有的邊,就稱此資源圖可完全簡化,此時一定沒有發生死鎖,相等于可以找到一個安全序列P1P_{1}P1?->P2P_{2}P2?。如果不能消除所有邊,此時就發生了死鎖,而且最終還連著邊的那些進程就是處于死鎖狀態的進程
比如下圖中,開始時讓P1P_{1}P1?再多持有一個R2R_{2}R2?資源,并且R2R_{2}R2?資源又分配了一個給P3P_{3}P3?
此時R2R_{2}R2?資源被分配干凈,所以P1P_{1}P1?在請求時被阻塞,相應P2P_{2}P2?進程也會被阻塞。因此只有P3P_{3}P3?能夠順利進行
P3P_{3}P3?結束之后雖然會歸還1個R2R_{2}R2?資源,但是仍然不滿足P1P_{1}P1?的需求,所以P1P_{1}P1?依然被阻塞,P2P_{2}P2?也還是被阻塞,發生死鎖
死鎖解除
解除死鎖:一旦檢測出死鎖發生,就應該立即解除死鎖。注意并不是系統中所有的進程都是死鎖狀態,使用死鎖檢測算法化簡資源分配圖后,還連著邊的那些進程就是需要進行解除的死鎖進程。解除方法主要有:
- 資源剝奪法:掛起(暫時放到外存上)某些死鎖進程,并搶占它的資源,將這些資源分配給其他的死鎖進程。但是應防止被掛起的進程長時間得不到資源而饑餓
- 撤銷進程法(終止進程法):強制撤銷部分,甚至全部死鎖進程,并剝奪這些進程的資源。這種方式的優點是實現簡單,但所付出的代價可能性會很大。因為有些進程可能已經運行了很長時間,已經接近結束了,一旦被終止可謂功虧一簣,以后還得從頭再來
- 進程回退法:讓一個或多個死鎖進程回退到足以避免死鎖的地步。這樣就要求系統要記錄進程的歷史信息,設置還原點
總結
以上是生活随笔為你收集整理的(数据库系统概论|王珊)第十一章并发控制-第二、三、四节:封锁、封锁协议活锁和死锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于运行SWT程序遇到的一个错误的总结
- 下一篇: MVC4验证用户登录特性实现方法