日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统:经典进程同步问题 之 生产者-消费者问题、读者-写者问题、哲学家进餐问题

發布時間:2024/9/30 windows 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统:经典进程同步问题 之 生产者-消费者问题、读者-写者问题、哲学家进餐问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

在進程同步中,經典的同步問題有:生產者-消費者問題、讀者-寫者問題、哲學家進餐問題。

一、生產者與消費者問題:

問題描述:使用一個緩沖區來保存物品,只有緩沖區沒有滿,生產者才可以放入物品;只有緩沖區不為空,消費者才可以拿走物品。

1、使用信號量實現生產者-消費者問題:

down?: 如果信號量大于 0 ,執行 -1 操作;如果信號量等于 0,進程睡眠,等待信號量大于 0;

up?:對信號量執行 +1 操作,喚醒睡眠的進程讓其完成 down 操作。

因為緩沖區屬于臨界資源,因此需要使用一個互斥量 mutex 來控制對緩沖區的互斥訪問。

為了同步生產者和消費者的行為,需要記錄緩沖區中物品的數量。數量可以使用信號量來進行統計,這里需要使用兩個信號量:empty 記錄空緩沖區的數量,full 記錄滿緩沖區的數量。其中,empty 信號量是在生產者進程中使用,當 empty 不為 0 時,生產者才可以放入物品;full 信號量是在消費者進程中使用,當 full 信號量不為 0 時,消費者才可以取走物品。

注意,不能先對緩沖區進行加鎖,再測試信號量。也就是說,不能先執行 down(mutex) 再執行 down(empty)。如果這么做了,那么可能會出現這種情況:生產者對緩沖區加鎖后,執行 down(empty) 操作,發現 empty = 0,此時生產者睡眠。消費者不能進入臨界區,因為生產者對緩沖區加鎖了,消費者就無法執行 up(empty) 操作,empty 永遠都為 0,導致生產者永遠等待下,不會釋放鎖,消費者因此也會永遠等待下去。

#define N 100 typedef int semaphore; semaphore mutex = 1; semaphore empty = N; semaphore full = 0;void producer() {while(TRUE) {int item = produce_item();down(&empty);down(&mutex);insert_item(item);up(&mutex);up(&full);} }void consumer() {while(TRUE) {down(&full);down(&mutex);int item = remove_item();consume_item(item);up(&mutex);up(&empty);} }

2、使用管程實現生產者-消費者問題:

?// 管程
?monitor ProducerConsumer
? ? condition full, empty;
? ? integer count := 0;
? ? condition c;

? ? procedure insert(item: integer);
? ? begin
? ? ? ? if count = N then wait(full);
? ? ? ? insert_item(item);
? ? ? ? count := count + 1;
? ? ? ? if count = 1 then signal(empty);
? ? end;

? ? function remove: integer;
? ? begin
? ? ? ? if count = 0 then wait(empty);
? ? ? ? remove = remove_item;
? ? ? ? count := count - 1;
? ? ? ? if count = N -1 then signal(full);
? ? end;
end monitor;

// 生產者客戶端
procedure producer
begin
? ? while true do
? ? begin
? ? ? ? item = produce_item;
? ? ? ? ProducerConsumer.insert(item);
? ? end
end;

// 消費者客戶端
procedure consumer
begin
? ? while true do
? ? begin
? ? ? ? item = ProducerConsumer.remove;
? ? ? ? consume_item(item);
? ? end
end;

?

二、讀者-寫者問題:

允許多個進程同時對數據進行讀操作,但是不允許讀和寫以及寫和寫操作同時發生。

一個整型變量 count 記錄在對數據進行讀操作的進程數量,一個互斥量 count_mutex 用于對 count 加鎖,一個互斥量 data_mutex 用于對讀寫的數據加鎖。

typedef int semaphore; semaphore count_mutex = 1; semaphore data_mutex = 1; int count = 0;void reader() {while(TRUE) {down(&count_mutex);count++;if(count == 1) down(&data_mutex); // 第一個讀者需要對數據進行加鎖,防止寫進程訪問up(&count_mutex);read();down(&count_mutex);count--;if(count == 0) up(&data_mutex);up(&count_mutex);} }void writer() {while(TRUE) {down(&data_mutex);write();up(&data_mutex);} }

?

三、哲學家進餐問題:

五個哲學家圍著一張圓桌,每個哲學家面前放著食物。哲學家的生活有兩種交替活動:吃飯以及思考。當一個哲學家吃飯時,需要先拿起自己左右兩邊的兩根筷子,并且一次只能拿起一根筷子。

下面是一種錯誤的解法,考慮到如果所有哲學家同時拿起左手邊的筷子,那么就無法拿起右手邊的筷子,造成死鎖。

#define N 5void philosopher(int i) {while(TRUE) {think();take(i); // 拿起左邊的筷子take((i+1)%N); // 拿起右邊的筷子eat();put(i);put((i+1)%N);} }

為了防止死鎖的發生,可以設置兩個條件:

  • 必須同時拿起左右兩根筷子;
  • 只有在兩個鄰居都沒有進餐的情況下才允許進餐。
#define N 5 #define LEFT (i + N - 1) % N // 左鄰居 #define RIGHT (i + 1) % N // 右鄰居 #define THINKING 0 #define HUNGRY 1 #define EATING 2 typedef int semaphore; int state[N]; // 跟蹤每個哲學家的狀態 semaphore mutex = 1; // 臨界區的互斥 semaphore s[N]; // 每個哲學家一個信號量void philosopher(int i) {while(TRUE) {think();take_two(i);eat();put_two(i);} }void take_two(int i) {down(&mutex);state[i] = HUNGRY;test(i);up(&mutex);down(&s[i]); }void put_two(i) {down(&mutex);state[i] = THINKING;test(LEFT);test(RIGHT);up(&mutex); }void test(i) { // 嘗試拿起兩把筷子if(state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] !=EATING) {state[i] = EATING;up(&s[i]);} }

?

?

文章轉自:https://github.com/CyC2018/CS-Notes/blob/master/docs/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F.md#%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8

總結

以上是生活随笔為你收集整理的操作系统:经典进程同步问题 之 生产者-消费者问题、读者-写者问题、哲学家进餐问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。