操作系统:生产者与消费者问题
使用信號量實現生產者-消費者問題?
問題描述:使用一個緩沖區來保存物品,只有緩沖區沒有滿,生產者才可以放入物品;只有緩沖區不為空,消費者才可以拿走物品。
因為緩沖區屬于臨界資源,因此需要使用一個互斥量 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);} }使用管程實現
4. 管程
使用信號量機制實現的生產者消費者問題需要客戶端代碼做很多控制,而管程把控制的代碼獨立出來,不僅不容易出錯,也使得客戶端代碼調用更容易。
c 語言不支持管程,下面的示例代碼使用了類 Pascal 語言來描述管程。示例代碼的管程提供了 insert() 和 remove() 方法,客戶端代碼通過調用這兩個方法來解決生產者-消費者問題。
monitor ProducerConsumerinteger i;condition c;procedure insert();begin// ...end;procedure remove();begin// ...end; end monitor;管程有一個重要特性:在一個時刻只能有一個進程使用管程。進程在無法繼續執行的時候不能一直占用管程,否者其它進程永遠不能使用管程。
管程引入了?條件變量?以及相關的操作:wait()?和?signal()?來實現同步操作。對條件變量執行 wait() 操作會導致調用進程阻塞,把管程讓出來給另一個進程持有。signal() 操作用于喚醒被阻塞的進程。
使用管程實現生產者-消費者問題?
// 管程 monitor ProducerConsumercondition full, empty;integer count := 0;condition c;procedure insert(item: integer);beginif count = N then wait(full);insert_item(item);count := count + 1;if count = 1 then signal(empty);end;function remove: integer;beginif count = 0 then wait(empty);remove = remove_item;count := count - 1;if count = N -1 then signal(full);end; end monitor;// 生產者客戶端 procedure producer beginwhile true dobeginitem = produce_item;ProducerConsumer.insert(item);end end;// 消費者客戶端 procedure consumer beginwhile true dobeginitem = ProducerConsumer.remove;consume_item(item);end end;?
總結
以上是生活随笔為你收集整理的操作系统:生产者与消费者问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统:虚拟内存的定义及实现方式
- 下一篇: 操作系统:读写问题