1. 程式人生 > >程序互斥軟體實現之Dekker演算法

程序互斥軟體實現之Dekker演算法

一. 為什麼需要互斥?

大多數系統允許多個程序共享資源(如CPU,IO裝置,硬碟等), 為了保證程序間能夠互不影響、安全正確地訪問這些共享資源, 就必須對程序訪問共享資源採取互斥控制.

 

二. 名詞說明:

臨界資源: 對於某一時刻僅允許一個程序訪問的共享資源.
臨界區: 訪問臨界資源的程式程式碼段.
互斥: 對程序排它地訪問臨界資源的控制手段, 某一時刻臨界區的程序只能為一個.

 

三. Dekker演算法思想:孔融讓梨, 任意程序在訪問關鍵區之前會先檢查其它程序是否也需要使用關鍵區,如果其它程序也需要使用關鍵區,並且其它程序也擁有執行許可權,這時當前程序就會等待其它程序訪問關鍵區完畢,若其它程序無法同時滿足兩個條件,那麼當前程序就會直接訪問關鍵區域.

 

虛擬碼:

 1 // 變數說明:
 2 // flag[0] = true 表示程序P0需要使用關鍵區
 3 // flag[1] = false 表示程序P1不需要使用關鍵區
 4 // turn = 0 表示程序P0具有訪問許可權
 5 // turn = 1 表示程序P1具有訪問許可權
 6 
 7 /* 程序P0行為 */
 8 void P0()
 9 {
10     while (true)
11     {
12         // P0需要使用關鍵區
13         flag[0] = true;
14         // 檢查P1是否也需要
15         while
(flag[1]) 16 { 17 // 檢查P1是否具有訪問許可權 18 if (turn == 1) 19 { 20 // P1也需要,P0讓給P1 21 flag[0] = false; 22 // P0等待P1執行完畢 23 while (turn == 1); 24 flag[0] = true; 25 } 26 }
27 28 // 臨界區程式碼 29 30 // 訪問完成,將許可權歸還P1 31 turn = 1; 32 // 程序P0使用完畢 33 flag[0] = false; 34 } 35 } 36 37 /* 程序P1行為, 與程序P0類似 */ 38 void P1() 39 { 40 while (true) 41 { 42 flag[1] = true; 43 while (flag[0] == 1) 44 { 45 if (turn == 0) 46 { 47 flag[1] = false; 48 while (turn == 0); 49 flag[1] = true; 50 } 51 } 52 53 // 臨界區程式碼 54 55 turn = 0; 56 flag[1] = false; 57 } 58 } 59 60 main() 61 { 62 // 建立兩個執行緒t1和t2 63 pthread_t t1, t2; 64 65 // 初始化條件 66 flag[0] = flag[1] = 0; 67 turn = 0; 68 69 int err; 70 71 // 執行緒t1模擬程序P0 72 err = pthread_create(&t1, NULL, (void*)P0, NULL); 73 if (err != 0) exit(-1); 74 // 執行緒t2模擬程序P1 75 err = pthread_create(&t2, NULL, (void*)P1, NULL); 76 if (err != 0) exit(-1); 77 78 pthread_join(t1, NUll); 79 pthread_join(t2, NUll); 80 81 exit(0); 82 }

 

不能再用單程序程式設計那樣一段程式碼從頭執行到底的"直線式"思維了。這是多進(線)程程式設計, 程式完全有可能在執行到任意一條語句時被中斷, 從而跳到另外一個程序執行另外一段程式碼.

 

Dekker演算法僅能進行兩個程序的互斥,對於兩個以上的互斥問題,實現起來相當複雜. 

 

總之,Dekker演算法首先使用狀態值的方式解決了序號訪問臨界區的弊端,使得程序可以互斥的訪問臨界資源,而最後結合了序號謙讓方式解決了因為避免死鎖而產生的僵局現象,就這樣循序漸進地用軟體方法解決了程序的互斥的問題.

 

參考:

https://blog.csdn.net/wsw875421872/article/details/17222219