inter-process communication的縮寫,含義是程序間通訊,是指兩個程序間交換資料的過程。
哲學家的生活包括兩個不同的階段:吃飯和思考
當乙個哲學家覺得餓時,他就試圖去取他左邊和右邊的叉子,每次拿一把,但是部分次序,如果成功地獲得了兩把叉子,他就吃一會兒,然後放下叉子繼續思考。
關鍵的問題就是:為每個哲學家寫一段程式來描述其行為而且不能思索,你可以做到嗎?
一種不正確的解法
#define n 5 //哲學家的數目
void philosopher(int i)
}
但是當所有哲學家同時拿起左邊的叉子,無法得到右邊的叉子——死鎖程式稍作修改:所有的哲學家都同時拿起左叉,看到右叉不可用,又都放下左叉,等一會兒,又同時拿起左叉,如此這般,永遠重複。對於這種情況,即所有的程式都在無限期地執行,但是都無法取得任何進展,就成為飢餓(starvation)。
對上例演算法可做一點改進,它既不會死鎖也不會飢餓:即,使用乙個二進位制訊號量對五個think
之後的語句進行保護。在開始拿叉子之前,哲學家先對訊號量mutex
執行down
操作。在放回叉子後,他要對mutex
執行up
操作。
從理論上講,該解法是可行的。但是從實力角度來看,有效能上的缺陷:任意時刻只能有乙個哲學家進餐。而五把叉子實際上允許有兩位哲學將同時進餐。
#define n 5 /* 哲學家數目 */
#define left (i+n-1)%n /* i的左鄰編號 */
#define right (i+1)%n /* i的右鄰編號 */
#define thinking 0 /* 哲學家在思考 */
#define hungry 1 /* 哲學家試圖拿起叉子 */
#define eating 2 /* 哲學家進餐 */
typedef int semaphore; /* 訊號量 */
int state[n]; /* 記錄每位哲學家狀態 */
semaphore mutex = 1; /* 臨界區的互斥 */
semaphore s[n]; /* 每位哲學家乙個訊號量 */
/* i: 哲學家編號,從0到n-1 */
void philosopher(int i)
}void take_forks(int i)
void put_forks(i)
void test(i)
}
上面給出的解法是沒有死鎖的,而且對於任意多位哲學家的情況都能獲得最大的並行度。它使用乙個陣列state
來記錄哲學家是在吃飯、思考還是餓了。乙個哲學家只有在兩個鄰座都不在進餐時,才允許轉換到進餐狀態。哲學家i的鄰居是由巨集left
和right
定義。
該程式使用了乙個訊號量陣列,每個訊號量對應於一位哲學家,這樣,所需的叉子被占用時,飢餓的哲學家就可以被阻塞。注意每個程序將歷程philosopher
作為朱**執行,而其他例程,如take_forks
、put_forks
和test
都只是普通的例程,而不是單獨的程序。
另乙個著名的問題是讀者—寫者問題,它建模了對資料庫的訪問。
例如,設想乙個飛機定票系統,其中有許多競爭的程序試圖讀寫其中的資料。多個程序同時讀是可以接受的,但如果乙個程序正在更新資料庫,則所有其他程序都不能訪問資料庫,即使讀操作也不行。這裡的問題是:如何對讀者和寫者進行程式設計?
程序a操作
程序b操作
是否允許讀讀
允許讀寫互斥
寫寫互斥
typedef int semaphore;
semaphore mutex = 1; /* 控制對rc的訪問 */
semaphore db = 1; /* 控制對資料庫的訪問 */
int rc = 0; /* 正在讀或想要讀的程序數 */
void reader(void)
}void writer(void)
}
第乙個讀者對訊號量db
執行down
。隨後的讀者給計數器rc
加1。當讀者離開時,它們遞減這個計數器,而最後乙個讀者則對db
執行up
,這樣就允許乙個阻塞的寫者可以訪問資料庫。
設想當乙個讀者在使用資料庫時,另乙個讀者也來訪問資料庫,由於同時允許多個讀者同時進行讀操作,所以第二個讀者也被允許進入,同理第三個及隨後更多的讀者都被允許進入。
IPC經典問題
而講minix的書籍 作業系統 設計與實現 也是當年linus torvalds創造linux的思想源泉。剛看了此書一章多,覺得此書寫得非常經典。看完本書講了ipc經典問題 哲學家進餐問題,讀者 寫者問題,理髮師理髮問題。這些經典問題主要解決了程序間競爭資源問題,提出了程序同步的設計模型。以下是理髮...
IPC 讀者 寫者問題
courtois et al於1971年提出。可以多讀取,但是寫入時不允許讀取 寫入。1 typedef int semaphore 2 semaphore mutex 1 3 semaphore db 1 4 int rc 0 5 void reader void 6 19 20void writ...
經典排序演算法的經典問題
問題描述 乙個陣列只含有三種元素 0,1,2,不使用計數排序,將0放在1的左邊,2放在1的右邊。分析 1.可借鑑快排中劃分的思想。將陣列分為,arr,2.遍歷arr,當發現0時,0區向右擴,發現2時,2區向左擴,3.當前元素進入2區時,結束。vector sortthreecolor vector ...