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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

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

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

?

在進(jìn)程同步中,經(jīng)典的同步問題有:生產(chǎn)者-消費(fèi)者問題、讀者-寫者問題、哲學(xué)家進(jìn)餐問題。

一、生產(chǎn)者與消費(fèi)者問題:

問題描述:使用一個(gè)緩沖區(qū)來保存物品,只有緩沖區(qū)沒有滿,生產(chǎn)者才可以放入物品;只有緩沖區(qū)不為空,消費(fèi)者才可以拿走物品。

1、使用信號量實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者問題:

down?: 如果信號量大于 0 ,執(zhí)行 -1 操作;如果信號量等于 0,進(jìn)程睡眠,等待信號量大于 0;

up?:對信號量執(zhí)行 +1 操作,喚醒睡眠的進(jìn)程讓其完成 down 操作。

因?yàn)榫彌_區(qū)屬于臨界資源,因此需要使用一個(gè)互斥量 mutex 來控制對緩沖區(qū)的互斥訪問。

為了同步生產(chǎn)者和消費(fèi)者的行為,需要記錄緩沖區(qū)中物品的數(shù)量。數(shù)量可以使用信號量來進(jìn)行統(tǒng)計(jì),這里需要使用兩個(gè)信號量:empty 記錄空緩沖區(qū)的數(shù)量,full 記錄滿緩沖區(qū)的數(shù)量。其中,empty 信號量是在生產(chǎn)者進(jìn)程中使用,當(dāng) empty 不為 0 時(shí),生產(chǎn)者才可以放入物品;full 信號量是在消費(fèi)者進(jìn)程中使用,當(dāng) full 信號量不為 0 時(shí),消費(fèi)者才可以取走物品。

注意,不能先對緩沖區(qū)進(jìn)行加鎖,再測試信號量。也就是說,不能先執(zhí)行 down(mutex) 再執(zhí)行 down(empty)。如果這么做了,那么可能會(huì)出現(xiàn)這種情況:生產(chǎn)者對緩沖區(qū)加鎖后,執(zhí)行 down(empty) 操作,發(fā)現(xiàn) empty = 0,此時(shí)生產(chǎn)者睡眠。消費(fèi)者不能進(jìn)入臨界區(qū),因?yàn)樯a(chǎn)者對緩沖區(qū)加鎖了,消費(fèi)者就無法執(zhí)行 up(empty) 操作,empty 永遠(yuǎn)都為 0,導(dǎo)致生產(chǎn)者永遠(yuǎn)等待下,不會(huì)釋放鎖,消費(fèi)者因此也會(huì)永遠(yuǎn)等待下去。

#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、使用管程實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者問題:

?// 管程
?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;

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

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

?

二、讀者-寫者問題:

允許多個(gè)進(jìn)程同時(shí)對數(shù)據(jù)進(jìn)行讀操作,但是不允許讀和寫以及寫和寫操作同時(shí)發(fā)生。

一個(gè)整型變量 count 記錄在對數(shù)據(jù)進(jìn)行讀操作的進(jìn)程數(shù)量,一個(gè)互斥量 count_mutex 用于對 count 加鎖,一個(gè)互斥量 data_mutex 用于對讀寫的數(shù)據(jù)加鎖。

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); // 第一個(gè)讀者需要對數(shù)據(jù)進(jìn)行加鎖,防止寫進(jìn)程訪問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);} }

?

三、哲學(xué)家進(jìn)餐問題:

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

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

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

為了防止死鎖的發(fā)生,可以設(shè)置兩個(gè)條件:

  • 必須同時(shí)拿起左右兩根筷子;
  • 只有在兩個(gè)鄰居都沒有進(jìn)餐的情況下才允許進(jì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]; // 跟蹤每個(gè)哲學(xué)家的狀態(tài) semaphore mutex = 1; // 臨界區(qū)的互斥 semaphore s[N]; // 每個(gè)哲學(xué)家一個(gè)信號量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]);} }

?

?

文章轉(zhuǎn)自: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

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。