当前位置:文档之家› 1实验1:生产者消费者问题

1实验1:生产者消费者问题

福建农林大学金山学院实验报告
系(教研室):专业:计算机科学与技术年级:
实验课程:生产者与消费者实验姓名:学号:
实验室号:1#608
计算机号:实验时间:指导教师签字:成绩:
实验1:生产者消费者问题
一、实验目的
生产者消费者问题是操作系统中经典的同步和互斥问题。

通过实验,要求学生掌握两者之间的同步信号量和互斥信号量的使用,更深刻了解临界资源、同步和互斥的概念。

二、实验要求
1.一组生产者通过一个具有N个缓冲区的缓冲池循环不断地向一组消费者提供产品。

2.建一个队列,队列的长度由n记录,定义两个指针,分别指向队列的头和尾消费者从头
指针读取数据,每读取一个数据把n--,生产者把数据写入尾指针,每写入一个数据就n++,当n=N的时候生产者暂停写入数据。

3.注意:缓冲池队列,用互斥锁保护。

三、实验内容和原理
1.分别画出生产者和消费者的流程图
页脚内容1
页脚内容2
2.针对生产者和消费者问题,可以分为哪几种情况,使用了哪些原语?分别代表什么
意思?过程如何?阐述哪些进程之间存在同步,哪些进程之间存在互斥。

3.缓冲区是否为临界资源?是否可以循环使用?通过什么来实现?举例说明(可画图)
四、实验环境
1.硬件:PC机;
2.软件:Wind ows操作系统、VC6.0。

页脚内容3
五、算法描述及实验步骤
#includ e<wind ows.h>
#includ e<iostream>
constunsignedshortSIZE_OF_BUFFER=10; unsignedshortProductID=0; unsignedshortConsumeID=0;
unsignedshortin=0;
unsignedshortout=0;
intg_buffer[SIZE_OF_BUFFER];
boolg_continue=true;
HANDLEg_hMutex;
HANDLEg_hFullSemaphore;
HANDLEg_hEmptySemaphore;
DWORDWINAPIProducer(LPVOID);
DWORDWINAPIConsumer(LPVOID);
intmain()
{g_hMutex=CreateMutex(NULL,FALSE,NULL);
页脚内容4
g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); constunsignedshortPRODUCERS_COUNT=3;
constunsignedshortCONSUMERS_COUNT=1;
constunsignedshortTHREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT; HANDLEhThreads[PRODUCERS_COUNT];
DWORDproducerID[CONSUMERS_COUNT];
DWORDconsumerID[THREADS_COUNT];
for(inti=0;i<PRODUCERS_COUNT;++i){
hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);
if(hThreads[i]==NULL)return-1;
}
for(i=0;i<CONSUMERS_COUNT;++i){
hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[i]); if(hThreads[i]==NULL)return-1;
}
whil e(g_continue){
页脚内容5
if(getchar()){//按回车后终止程序运行
g_continue=false;
}
}
return0;
}
voidProduce()
{std::cerr<<"Producing"<<++ProductID<<"...";
std::cerr<<"Succeed"<<std::endl;
}
voidAppend()
{std::cerr<<"Appendingaproduct...";
g_buffer[in]=ProductID;
in=(in+1)%SIZE_OF_BUFFER;
std::cerr<<"Succeed"<<std::endl;
for(inti=0;i<SIZE_OF_BUFFER;++i){
std::cout<<i<<":"<<g_buffer[i];
页脚内容6
if(i==in)std::cout<<"<--生产";
if(i==out)std::cout<<"<--消费";
std::cout<<std::endl;
}
}
voidTake()
{std::cerr<<"Takingaproduct...";
ConsumeID=g_buffer[out];
out=(out+1)%SIZE_OF_BUFFER;
std::cerr<<"Succeed"<<std::endl;
for(inti=0;i<SIZE_OF_BUFFER;++i){
std::cout<<i<<":"<<g_buffer[i];
if(i==in)std::cout<<"<--生产";
if(i==out)std::cout<<"<--消费";
std::cout<<std::endl;}
}
voidConsume()
页脚内容7
{std::cerr<<"Consuming"<<ConsumeID<<"..."; std::cerr<<"Succeed"<<std::endl;
}
DWORDWINAPIProducer(LPVOIDlpPara)
{whil e(g_continue){
WaitForSingl eObject(g_hFullSemaphore,INFINITE); WaitForSingl eObject(g_hMutex,INFINITE); Produce();
Append();
Sl eep(1500);
ReleaseMutex(g_hMutex); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); }
return0;
}
DWORDWINAPIConsumer(LPVOIDlpPara)
{whil e(g_continue){
页脚内容8
WaitForSingl eObject(g_hEmptySemaphore,INFINITE); WaitForSingl eObject(g_hMutex,INFINITE);
Take();
Consume();
Sl eep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullSemaphore,1,NULL);
}
return0;
}
六、调试过程
程序有错误:
在94和108行分别少了两个封号。

经改正后无错误如图所示:
七、实验结果
七、总结
页脚内容9
通过这次试验我了解了生产者消费者问题是操作系统中经典的同步和互斥问题。

基本上掌握了两者之间的同步信号量和互斥信号量的使用,更深刻了解临界资源、同步和互斥的概念。

并且在错误的调试中对知识有了更深的掌握。

附录:
页脚内容10。

相关主题