經典的IPC問題

2022-06-07 01:42:17 字數 2607 閱讀 2169

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的鄰居是由巨集leftright定義。

該程式使用了乙個訊號量陣列,每個訊號量對應於一位哲學家,這樣,所需的叉子被占用時,飢餓的哲學家就可以被阻塞。注意每個程序將歷程philosopher作為朱**執行,而其他例程,如take_forksput_forkstest都只是普通的例程,而不是單獨的程序。

另乙個著名的問題是讀者—寫者問題,它建模了對資料庫的訪問。

例如,設想乙個飛機定票系統,其中有許多競爭的程序試圖讀寫其中的資料。多個程序同時讀是可以接受的,但如果乙個程序正在更新資料庫,則所有其他程序都不能訪問資料庫,即使讀操作也不行。這裡的問題是:如何對讀者和寫者進行程式設計?

程序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 ...