实验报告
课程名称操作系统实验名称进程通信实例(消费者生产者问题)
实验目的
用信号量实现生产者消费者问题
实验原理与方案
生产者和消费者问题是多个相互合作的进程之间的一种抽象。生产者和消费者之间的关系:
1.对缓冲区的访问是互斥的。由于两者都会修改缓冲区,因此,一方修改缓冲区时,另一方不能修改,这就是互斥。
2.一方的行为影响另一方。缓冲区不空,才能消费,何时不空?生产了就不空;缓冲区满,就不能生产,何时不满?消费了就不满。这是同步关系。
为了描述这种关系,一方面,使用共享内存代表缓冲区;另一方面,使用互斥信号量控制对缓冲区的访问,使用同步信号量描述两者的依赖关系。
共享存储是进程间通信的一种手段,通常,使用信号量同步或互斥访问共享存储。共享存储的原理是将进程的地址空间映射到一个共享存储段。在LINUX下,通过使用shmget函数创建或者获取共享内存。
执行结果与分析
如下图所示:
先生产的产品总是先被消费。
详细代码
#include<stdio.h>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/sem.h>
#include<stdlib.h>
#define SHM_SIZE(1024*1024)
#define SHM_MODE0600
#define SEM_MODE0600
#if defined(__GNU_LIBRARY__)&&!defined(_SEM_SEMUN_UNDEFINED) /*union semun is defined by including<sys/sem.h>*/ #else
/*according to X/OPEN we have to define it ourselves*/ union semun{
int val;
struct semid_ds*buf;
unsigned short*array;
};
#endif
struct ShM{
int start;
int end;
}*pSM;
const int N_CONSUMER=1//消费者数量
const int N_BUFFER=10;//缓冲区容量
int shmId=-1,semSetId=-1;
union semun su;//sem union,用于初始化信号量
//semSetId表示信号量集合的id
//semNum表示要处理的信号量在信号量集合中的索引
进程间通信实验void waitSem(int semSetId,int semNum)
{
struct sembuf sb;
sb.sem_num=semNum;
sb.sem_op=-1;//表示要把信号量减一
sb.sem_flg=SEM_UNDO;//
//第二个参数是sembuf[]类型的,表示数组
/
/第三个参数表示第二个参数代表的数组的大小if(semop(semSetId,&sb,1)<0){
perror("waitSem failed");
exit(1);
}
}
void sigSem(int semSetId,int semNum)
{
struct sembuf sb;
sb.sem_num=semNum;
sb.sem_op=1;
sb.sem_flg=SEM_UNDO;
/
/第二个参数是sembuf[]类型的,表示数组
//第三个参数表示第二个参数代表的数组的大小if(semop(semSetId,&sb,1)<0){
perror("waitSem failed");
exit(1);
}
}
//必须在保证互斥以及缓冲区不满的情况下调用
void produce()
{
int last=pSM->end;
pSM->end=(pSM->end+1)%N_BUFFER;
printf("生产%d\n",last);
}
//必须在保证互斥以及缓冲区不空的情况下调用
void consume()
{
int last=pSM->start;
pSM->start=(pSM->start+1)%N_BUFFER;
printf("消耗%d\n",last);
}
void init()
{
/
/缓冲区分配以及初始化
if((shmId=shmget(IPC_PRIVATE,SHM_SIZE,SHM_MODE))<0) {
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论