生产者与消费者算法的实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验六信号量

厦门大学软件学院

吴清强

一.实验目的

⏹加强对进程概念的理解。

⏹进一步了解并发执行的实质。

⏹分析进程争用资源的现象,学习解决进程互斥的方法

⏹了解Linux系统中进程通信的基本原理

二.相关知识

⏹进程的概念。

⏹进程与程序的区别。

⏹进程并发执行的概念。

⏹进程互斥的概念

⏹进程通信的基本原理

三.实验内容

⏹使用信号量实现有限缓冲区的生产者和消费者问题

⏹使用信号量实现读进程具有优先权的读者和写者问题四.实验环境

⏹PC + Linux Red Hat操作系统

⏹GCC

1. 使用信号量实现有限缓冲区的生产

者和消费者问题

一.程序流程图

生产者进程生产流程图

消费者进程消费流程图

二.源代码

1、生产者生产进程函数

DWORD WINAPI Producer(LPVOID lpParameter){

while(true){

for(int j=0;j<4;j++){

if(buffer[j]==0){//找到空缓冲区

if(lock[j]==false){//同步锁为false,可以进行操作

lock[j]=true;//加锁,防止其他线程操作此缓冲区

if(buffer[j]<1){//限定一个缓冲区只能存放一个资源

++buffer[j];//模拟生产资源

cout<<"生产一个资源,放入缓冲区"<

lock[j]=false;//解锁

break;//一次生产一个

}

}

if(j==3){

cout<<"找不到空缓冲区,等待中。。"<

Sleep(2000);

}

}

}

}

return 0;

}

2、消费者消费进程函数

DWORD WINAPI Customer(LPVOID lpParameter)

{

while(true){

for(int n=0;n<4;n++){

if(buffer[n]==1){//找到满缓冲区

if(lock[n]==false){//同步锁为false,可以进行操作

lock[n]=true;//加锁,防止其他线程操作此缓冲区

if(buffer[n]>=1){

--buffer[n];//模拟消费资源

cout<<"消费一个资源,从缓冲区"<

lock[n]=false;//解锁

break;//一次生产一个

}

}

}

if(n==3){

cout<<"找不到满缓冲区,等待中。。"<

Sleep(2000);

}}}}

3、主函数,创建5个进程,其中3个生产者进程,2个消费者进程

int main(int argc,char* argv[])

{

HANDLE handle[3];

DWORD dw1,dw2,dw3,dw4,dw5;//创建5个进程

handle[0]=CreateThread(NULL,0,Producer,NULL,0,&dw1);

handle[1]=CreateThread(NULL,0,Producer,NULL,0,&dw2);

handle[2]=CreateThread(NULL,0,Producer,NULL,0,&dw3);

handle[3]=CreateThread(NULL,0,Customer,NULL,0,&dw4);

handle[4]=CreateThread(NULL,0,Customer,NULL,0,&dw5);

}

·三、试验结果

3个生产者2个消费者,共享4个缓冲区,运行结果如下:

1、一个生产者生产,一个消费者消费:

1、两个生产者连续生产,两个消费者连续消费:

2、多个生产者于多个消费者进行生产消费操作:

2.使用信号量实现读进程具有优先权的

读者和写者问题

.

一、程序流程图

二、源代码

#include

#include

#include

#include

#include

#include

int *critical;

int createSem()//创建信号量

{

return semget((key_t)1000,2,IPC_CREAT|0600);

}//the second parameter in semget is the number of signal we will create void initSignal(int semid,int index,int value)//初始化信号量

{

semctl(semid,index,SETV AL,value);

}

void make_critical () //创建缓冲区

{

critical=mmap(NULL,10*sizeof(int),PROT_READ|

PROT_WRITE,MAP_SHARED|

MAP_ANONYMOUS,-1,0);

critical[0]=-1;//the value of the critical file is init as -1

critical[1]=0;//the reader count is 0;

}

void semWait(int semid,int index)//判断当前进程是否进入缓冲区,被占用就挂起

{

struct sembuf sem_buf;

sem_buf.sem_num=index;

sem_buf.sem_op=-1;

sem_buf.sem_flg=SEM_UNDO;

semop(semid,&sem_buf,1);

}

void semSignal(int semid,int index)//唤醒一个在阻塞队列中等待的进程{

struct sembuf sem_buf;

sem_buf.sem_num=index;

sem_buf.sem_op=1;

sem_buf.sem_flg=SEM_UNDO;

semop(semid,&sem_buf,1);

}

//为了让读者优先,当读者获得控制权时,写者进程必须挂起;当第一个读者进程到来(等到写者进程释放控制权)时,第一个读者进程获得优先权,接着其他读者进程不再等待,同时执行。

//故而用critical[1]记录读者进程读到的内容,用semid[0]控制读者或写者进程,用semid[1]更新critical[1]的值

void reader(int semid)

{

while(1)

{

semWait(semid,1);

critical[1]++;

if(critical[1]==1)

semWait(semid,0);

相关文档
最新文档