操作系统(四) | 经典进程的同步问题(生产者--消费者问题、哲学家进餐问题、读者--写者问题)
生活随笔
收集整理的這篇文章主要介紹了
操作系统(四) | 经典进程的同步问题(生产者--消费者问题、哲学家进餐问题、读者--写者问题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 生產者--消費者問題
- 分析
- 實現
- 哲學家進餐問題
- 方法一:最多4人同時拿左筷子,最終保證一人能進餐
- 方法二:同時給左右筷子
- 解法1:AND信號量
- 解法2:信號量保護機制
- 方法三:讓奇數先左后右,讓偶數先右后左
- 讀者--寫者問題
- 分析
- 實現
前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到網站。點擊這里
生產者–消費者問題
分析
- P1~Pl 向BUFF存信息,C1~Cm 從BUFF取信息。
- 不能對同一個信息既存又取,因此P進程和C進程互斥(mutex)
- BUFF中有空位,P進程才能存信息(empty)
- BUFF中有信息,C進程才能取信息(full)
實現
int in = 0, out = 0; // 在BUFF中要操作(存消息,取消息)的位置 item buff[n]; // 創建BUFF semaphore mutex= 1, empty = n, full = 0; void producer(){do{產生一個消息并放到nextp里wait(empty); // 先檢驗是否為空wait(mutex); // 后檢驗是否互斥。順序顛倒,在滿的情況下,// 會導致mutex無法釋放,導致死鎖buff[in] = nextp;in = (in+1)%n; // 讓in指向下一個位置signal(mutex); // 釋放互斥信號signal(full); // 放進去信息了,full+1}while(True) }void consumer(){do{wait(full);wait(mutex);nextc = buff[out];out = (out+1) mod n;signal(mutex);signal(empty);消費nextc中的產品}while(True) }void main(){cobeginproducer();consumer();coend }注意:
- 每個進程中 wait(mutex)和 signal(mutex)成對存在
- 整個程序中 wait(empty/full)和 signal(empty/full)成對存在
- wait()順序不能顛倒,先資源再互斥,避免死鎖
哲學家進餐問題
方法一:最多4人同時拿左筷子,最終保證一人能進餐
semaphore chopsticks[5] = {1,1,1,1,1} // 5根筷子 semaphore r = 4 // 最多4個人同時拿左筷子 void ohilosopher(int i) {while(true){think();wait(r);// 看看有幾個人拿了左筷子wait(chopsticks[i]); // 拿左筷子wait(chopsticks[(i+1)mod 5]; // 拿有筷子eat(); // 吃signal(chopsticks[(i+1)) mod 5]; //給出筷子signal(chopsticks[i]);// 給出筷子signal(r); // 1個吃完了,又允許1個人拿左筷子了think();} }方法二:同時給左右筷子
解法1:AND信號量
semaphore chopsticks[5] = {1,1,1,1,1} void philosopher(int i){while(true){think();Swait(chopsticks [i] ; chopstick[i+1] mod 5); // 用AND信號量同時給左右筷子eat(); // 吃Ssignal(chopstick[(i+1) mod 5];chopstick[i]) // 吃完釋放一雙筷子think();} }解法2:信號量保護機制
semaphore mutex = 1 semaphore chopsticks[5] = {1,1,1,1,1} void philosopher(int i){while(true){think();wait(mutex);wait(chopstick[i]);wait(chopstick[(i+1) mod 5]);signal(mutex);eat();signal(chopstick[i]);signal(chopstick[(i+1) mod 5]);think();} }方法三:讓奇數先左后右,讓偶數先右后左
semaphore chopsticks[5] = {1,1,1,1,1] void philosopher(int i){while(true){if(i mod 2 == 0){wait(chopstick[(i+1) mod 5);wait(chopstick[i]);eat();signal(chopstick[i]);signal(chopstick[(i+1) mod 5]);}else{wait(chopstick[i]);wait(chopstick[(i+1) mod 5);eat();signal(chopstick[(i+1) mod 5]);signal(chopstick[i]);}} }讀者–寫者問題
分析
- 寫者和寫者之間互斥,寫者和讀者之間互斥
- 只要有一個讀者,寫者就不能去寫
實現
int Readcount = 0; // 記錄有幾個讀者在讀 semaphore rmutex = 1; // 讀寫互斥 semaphore wmutex = 1;// 讀者之間對Readcount訪問互斥 void Reader(){do{wait(rmutex);if (Readcount == 0) // 判斷是否是第一個讀者wait(wmutex);Readcount++;signal(rmutex);read();wait(rmutex);Readcount--;if (Readcount == 0){ // 判斷是否是最后一個讀者signal(wmutex);signal(wmutex);}while(true) }void Writer(){while(true){wait(wmutex);寫;signal(wmutex);}本文哲學家進餐問題參考【操作系統】“哲學家進餐”問題
總結
以上是生活随笔為你收集整理的操作系统(四) | 经典进程的同步问题(生产者--消费者问题、哲学家进餐问题、读者--写者问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统(三)| 进程同步详解(主要任务
- 下一篇: 在Windows下使用gcc