資源簡介
抽煙者問題。假設一個系統中有三個抽煙者進程,每個抽煙者不斷地卷煙并抽
煙。抽煙者卷起并抽掉一顆煙需要有三種材料:煙草、紙和膠水。一個抽煙者有煙
草,一個有紙,另一個有膠水。系統中還有兩個供應者進程,它們無限地供應所有
三種材料,但每次僅輪流提供三種材料中的兩種。得到缺失的兩種材料的抽煙者在
卷起并抽掉一顆煙后會發信號通知供應者,讓它繼續提供另外的兩種材料。這一過
程重復進行。 請用以上介紹的 IPC 同步機制編程,實現該問題要求的功能。

代碼片段和文件信息
#include?“ipc.h“
int?main(int?argcchar?*argv[])
{
int?rate;
//可在在命令行第一參數指定一個進程睡眠秒數以調解進程執行速度
if(argv[1]?!=?NULL)?rate?=?atoi(argv[1]);
else?rate?=?3;?//不指定為?3?秒
//共享內存?使用的變量
buff_key?=?101;?//緩沖區任給的鍵值
buff_num?=?3;?//緩沖區任給的長度
cget_key?=?103;?//消費者取產品指針的鍵值
cget_num?=?1;?//指針數
shm_flg?=?IPC_CREAT?|?0644;?//共享內存讀寫權限
//獲取緩沖區使用的共享內存buff_ptr?指向緩沖區首地址
buff_ptr?=?(char?*)set_shm(buff_keybuff_numshm_flg);
//獲取消費者取產品指針cget_ptr?指向索引地址
cget_ptr?=?(int?*)set_shm(cget_keycget_numshm_flg);
//信號量使用的變量
prod_key?=?201;?//生產者同步信號燈鍵值
cmtx_key?=?203;?//生產者互斥信號燈鍵值
c_PG_key?=?301;//消費者同步信號燈鍵值
c_TP_key?=?302;//消費者互斥信號燈鍵值
c_TG_key?=?303;//消費者互斥信號燈鍵值
sem_flg?=?IPC_CREAT?|?0644;?//信號燈操作權限
//生產者同步信號燈初值設為緩沖區最大可用量
sem_val?=?1;
//獲取生產者同步信號燈引用標識存?prod_sem
prod_sem?=?set_sem(prod_keysem_valsem_flg);
//消費者初始無產品可取同步信號燈初值設為?0
sem_val?=?0;
//獲取消費者同步信號燈引用標識存?cons_sem
c_PG_sem?=?set_sem(c_PG_keysem_valsem_flg);
c_TP_sem?=?set_sem(c_TP_keysem_valsem_flg);
c_TG_sem?=?set_sem(c_TG_keysem_valsem_flg);
//消費者互斥信號燈初值為?1
sem_val?=?1;
//獲取消費者互斥信號燈引用標識存?pmtx_sem
cmtx_sem?=?set_sem(cmtx_keysem_valsem_flg);
int?pid1?pid2;
pid1?=?fork();
if(pid1?==?0)?{
????//循環執行模擬消費者不斷取產品
????while(1){
????????//如果無產品消費者阻塞
????????down(c_PG_sem);
????????//如果另一消費者正在取產品本消費者阻塞
????????down(cmtx_sem);
????????//用讀一字符的形式模擬消費者取產品報告本進程號和獲取的字符及讀取的位置
????????sleep(rate);
????????printf(“%d吸煙者有煙草T得到紙%c和膠水%c開始吸煙……\n“
????????????getpid()buff_ptr[*cget_ptr?+?1]buff_ptr[*cget_ptr?+?2]);
????????//喚醒阻塞的消費者
????????up(cmtx_sem);
????????//喚醒阻塞的生產者
????????up(prod_sem);
????}
}?else?{
????pid2?=?fork();
????if(pid2?==?0)?{
????????//循環執行模擬消費者不斷取產品
????????while(1){
????????????//如果無產品消費者阻塞
????????????down(c_TP_sem);
????????????//如果另一消費者正在取產品本消費者阻塞
????????????down(cmtx_sem);
????????????//用讀一字符的形式模擬消費者取產品報告本進程號和獲取的字符及讀取的位置
????????????sleep(rate);
????????????printf(“%d吸煙者有膠水G得到紙%c和煙草%c開始吸煙……\n“
????????????????getpid()buff_ptr[*cget_ptr?+?1]buff_ptr[*cget_ptr]);
????????????//喚醒阻塞的消費者
????????????up(cmtx_sem);
????????????//喚醒阻塞的生產者
????????????up(prod_sem);
????????}
????}?else?{
????????//循環執行模擬消費者不斷取產品
????????while(1){
????????????//如果無產品消費者阻塞
????????????down(c_TG_sem);
????????????//如果另一消費者正在取產品本消費者阻塞
????????????down(cmtx_sem);
????????????//用讀一字符的形式模擬消費者取產品報告本進程號和獲取的字符及讀取的位置
????????????sleep(rate);
????????????printf(“%d吸煙者有紙P得到膠水%c和煙草%c開始吸煙……\n“
????????????????getpid()buff_ptr[*cget_ptr?+?2]buff_ptr[*cget_ptr]);
????????????//喚醒阻塞的消費者
????????????up(cmtx_sem);
????????????//喚醒阻塞的生產者
????????????up(prod_sem);
????????}
????????}
}
return?EXIT_SUCCESS;
}
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????目錄???????????0??2017-04-12?19:44??吸煙者問題\
?????文件???????20265??2017-04-12?19:44??吸煙者問題\consumer
?????文件????????3788??2017-04-12?19:27??吸煙者問題\consumer.c
?????文件????????3788??2017-04-12?19:27??吸煙者問題\consumer.c~
?????文件???????10904??2017-04-12?19:44??吸煙者問題\consumer.o
?????文件????????2727??2017-04-12?19:28??吸煙者問題\ipc.c
?????文件????????2727??2017-04-12?19:28??吸煙者問題\ipc.c~
?????文件????????1115??2017-04-12?19:29??吸煙者問題\ipc.h
?????文件????????1115??2017-04-12?19:29??吸煙者問題\ipc.h~
?????文件???????13296??2017-04-12?19:44??吸煙者問題\ipc.o
?????文件?????????377??2017-04-12?19:30??吸煙者問題\makefile
?????文件?????????377??2017-04-12?19:30??吸煙者問題\makefile~
?????文件???????20475??2017-04-12?19:43??吸煙者問題\producer
?????文件????????5597??2017-04-12?19:27??吸煙者問題\producer.c
?????文件????????5597??2017-04-12?19:26??吸煙者問題\producer.c~
?????文件???????13920??2017-04-12?19:43??吸煙者問題\producer.o
評論
共有 條評論