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

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

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

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

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

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

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

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

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

五、算法描述及实验步骤
#include <>
#include <iostream>
const unsigned short SIZE_OF_BUFFER = 10;
unsigned short ProductID = 0;
unsigned short ConsumeID = 0;
unsigned short in = 0;
unsigned short out = 0;
int g_buffer[SIZE_OF_BUFFER];
bool g_continue = true;
HANDLE g_hMutex;
HANDLE g_hFullSemaphore;
HANDLE g_hEmptySemaphore;
DWORD WINAPI Producer(LPVOID);
DWORD WINAPI Consumer(LPVOID);
int main()
{ g_hMutex = CreateMutex(NULL,FALSE,NULL);
g_hFullSemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);
g_hEmptySemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);
const unsigned short PRODUCERS_COUNT = 3;
const unsigned short CONSUMERS_COUNT = 1;
const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;
HANDLE hThreads[PRODUCERS_COUNT];
DWORD producerID[CONSUMERS_COUNT];
DWORD consumerID[THREADS_COUNT];
for (int i=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;
}
while(g_continue){
if(getchar()){ . ";
std::cerr << "Succeed" << std::endl;
}
void Append()
{ std::cerr << "Appending a product ... ";
g_buffer[in] = ProductID;
in = (in+1)%SIZE_OF_BUFFER;
std::cerr << "Succeed" << std::endl;
for (int i=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;
}
}
void Take()
{ std::cerr << "Taking a product ... ";
ConsumeID = g_buffer[out];
out = (out+1)%SIZE_OF_BUFFER;
std::cerr << "Succeed" << std::endl;
for (int i=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; }
}
void Consume()
{ std::cerr << "Consuming " << ConsumeID << " ... "; std::cerr << "Succeed" << std::endl;
}
DWORD WINAPI Producer(LPVOID lpPara)
{ while(g_continue){
WaitForSingleObject(g_hFullSemaphore,INFINITE); WaitForSingleObject(g_hMutex,INFINITE);
Produce();
Append();
Sleep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptySemaphore,1,NULL);
}
return 0;
}
DWORD WINAPI Consumer(LPVOID lpPara)
{ while(g_continue){
WaitForSingleObject(g_hEmptySemaphore,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
Take();
Consume();
Sleep(1500);
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullSemaphore,1,NULL);
}
return 0;
}
六、调试过程
程序有错误:
在94 和108行分别少了两个封号。

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

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

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

附录:。

相关主题