操作系统进程同步
实验二生产者与消费者
1. 实验目的
利用Windows 提供的API 函数,编写程序,解决生产者与消费者问题,实现进程的互斥与同步。
背景知识:
本实验要求设计在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。
生产者线程生产物品时,若无空缓冲区可用,生产者线程必须等待消费者线程释放出一个空缓冲区;消费者线程消费物品时,若缓冲区为空,消费者线程将被阻塞,直到新的物品被生产出来。
本实验要求设计并实现一个进程,该进程拥有一个生产者线程和一个消费者线程,它们使用N 个不同的缓冲区(N 为一个确定的数值,例如N=32)。
需要使用如下信号量:
(1)一个互斥信号量,用以阻止生产者线程和消费者线程同时操作缓冲区列表;
(2)一个信号量,当生产者线程生产出一个物品时可以用它向消费者线程发出信号;
(3)一个信号量,消费者线程释放出一个空缓冲区时可以用它向生产者线程发出信号;
2. 实验内容
进程的互斥与同步。编写一段程序,模拟生产者和消费者线程,实现进程的互斥与同步。 利用VC++6.0实现上述程序设计和调试操作,对于生产者和消费者线程操作的成功与否提供一定的提示框。
通过阅读和分析实验程序,熟悉进程的互斥与同步的概念。
3. 实验代码
#include
#include "windows.h"
#include
#include "process.h"
using namespace std;
#define N 5 //定义缓冲区的长度
#define WaitTime 1000
//定义信号量
HANDLE m_S_Empty;// 生产者Semaphore
HANDLE m_S_Full; // 消费者Semaphore
HANDLE m_M_Mutex;//互斥
int buffer[N]; //定义共享缓冲区
int n;//生产后放入缓冲区的数据
intpptr;//记录最新生产的位置
intcptr;//记录最新消费的位置
DWORD dwThread;
void Producer();
void Consumer();
DWORD __stdcallCreateProducerThread(LPVOID)//函数的类型转换
{
Producer();
return 0;
}
DWORD __stdcallCreateConsumerThread(LPVOID)//函数的类型转换
{
Consumer();
return 0;
}
int _tmain(intargc, _TCHAR* argv[])
{
int a;
//创建生产者和消费者线程
CreateThread(NULL, 0, CreateProducerThread, NULL,0, &dwThread);//生产者线程 CreateThread(NULL, 0, CreateConsumerThread, NULL, 0, &dwThread);//消费者进程
m_S_Empty = CreateSemaphore(NULL, N, N, NULL);//设置生产者信号量,初始计数为N m_S_Full = CreateSemaphore(NULL, 0, N, NULL);//设置消费者信号量,初始计数为0 m_M_Mutex = CreateMutex(NULL, FALSE, (LPCWSTR)"sample07");//设置互斥信号量 cin>> a;//等待I/O
return 0;
}
void Producer()
{ /*程序所需其他代码*/
while (TRUE)
{
/*程序所需其他代码*/
/*生产一个物品;*/
if (WaitForSingleObject(m_S_Empty, WaitTime) == WAIT_OBJECT_0)//判断是否已满 {
if (WaitForSingleObject(m_M_Mutex, WaitTime) == WAIT_OBJECT_0)//判断能否进入临界区
{
}
}
}
}
void Consumer()
{ /*将所生产的物品放到指定的缓冲区中;*/ n++; buffer[pptr] = n;//将生产的物品放入缓冲区 cout
/*程序所需其他代码*/
while (TRUE)
{
/*程序所需其他代码*/
if (WaitForSingleObject(m_S_Full, WaitTime) == WAIT_OBJECT_0)//判断是否为空 {
if (WaitForSingleObject(m_M_Mutex, WaitTime) == WAIT_OBJECT_0)//判断能否进入临界区
{
/*取出一个物品*/
cout
buffer[cptr] = 0;//消费后重置当前位置的缓冲区
cptr = (cptr + 1) % N;//缓冲区视为环形存储器
ReleaseMutex(m_M_Mutex);//互斥信号量+1
Sleep(50);//修改睡眠时间可以调整消费的速度
ReleaseSemaphore(m_S_Empty, 1, NULL);//生产者信号量+1
}
}
}
}
4. 运行截图
5. 实验中遇到的问题和解决方法 问题:CreateThread 函数参数不匹配
解决方法:将Producer 函数和Consumer 函数转换返回类型