资源简介
抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽
烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟
草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有
三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在
卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过
程重复进行。 请用以上介绍的 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
评论
共有 条评论