一.实验内容:
抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过程重复进行。 请用以上介绍的IPC同步机制编程,实现该问题要求的功能。
二.实验思路:
1.生产者要能提供三种组合的原料:烟草,纸(SP),烟草,胶水(SG),或是纸和胶水(PG),这就需要一个随机数,来决定提供哪种组合的原料。因为需要两个供应者,所以要两个生产者,两个生产者生产的内容一样,决定通过父子进程来实现。因为父子进程同时向一个临界区里写东西,所以加上互斥。并且生产者能发送三种信号来唤醒不同的消费者。
2.需要三个消费者分别消费不同的内容,通过父进程创建两个子进程来实现,父进程和两个子进程分别执行不同的内容,这个和实验一的内容很相似。三个进程在取东西对临界区进行修改的时候要互斥。
3.因为开始时没有资源,所以将唤醒消费者的三个信号的信号量初始值都设为0,因为生产者一次仅供应一个消费者,所以将消费者唤醒生产者的那个信号量初始值设为1。控制互斥的两个信号量pmtx和cmtx都设为1。
代码如下:
ipc.h:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<sys/msg.h>
#define BUFSZ 256
int get_ipc_id(char*proc_file,key_t key);
char *set_shm(key_t shm_key,int shm_num,int shm_flag);
int set_msq(key_t msq_key,int msq_flag);
int set_sem(key_t sem_key,int sem_val,int sem_flag);
int down(int sem_id);
int up(int sem_id);
typedef union semuns{
int val;
}Sem_uns;
typedef struct msgbuf{
long mtype;
char mtext[1];
}Msg_buf;
key_t buff_key;
int buff_num;
char *buff_ptr;
key_t pput_key;
int pput_num;
int *pput_ptr;
key_t cget_key;
int cget_num;
int *cget_ptr;
//producer semaphore
key_t prod_key;
key_t pmtx_key;
int prod_sem;
int pmtx_sem;
//consumer semaphore
key_t c_PG_ke