问题描述
用信号量模拟生产者-消费者问题的过程。生产者和消费者两个线程共享同一个缓冲区,生产者不断向缓冲区中添加产品,消费者从缓冲区中消费产品。要保证缓冲区满了之后生产者不能再继续添加产品,需要等消费者至少消费一个产品之后生产者才能继续生产产品;缓冲区空了之后消费者不能再消费产品,需要等生产者至少生产一个产品之后消费者才能继续消费产品。
向缓冲区中添加产品和从缓冲区消费产品需要互斥操作保持同步。
生产者需要等待缓冲区有空间才能生产产品;消费者也不能在缓冲区为空时消费产品。这两个过程需要信号量来通知进行。
设置三个信号量
Mutex信号量实现生产者和消费之间的间接相互制约关系,资源共享,在某一时刻只能有一个享用资源。
Full、Empty信号量实现生产者和消费者之间的直接相互制约关系,进程合作。Empty为生产者的约束,缓冲区满使生产者不能操作。Full为消费者的制约,缓冲区空使消费者不能操作。
完整代码
#include <iostream>
#include <fstream>
#include <Windows.h>
#include <process.h>
using namespace std;
#define BUFFER_SIZE 16
char buffer[BUFFER_SIZE]; //缓冲区
int in = 0, out = 0;
HANDLE Full;
HANDLE Mutex;
HANDLE Empty;
//初始化显示缓冲区,把空的标记为 “*”
void InitBuffer()
{
for (int i = 0;i < BUFFER_SIZE;i++)
{
buffer[i] = '*';
}
}
//显示缓冲区
void showBuffer()
{
cout << "缓冲区存储情况为(*为无产品):";
for (int i = 0;i < BUFFER_SIZE;i++)
{
cout << buffer[i] << " ";
}
cout << endl;
}
//生产者
DWORD WINAPI Producer(LPVOID)
{
do
{
WaitForSingleObject(Empty,INFINITE);
WaitForSingleObject(Mutex, INFINITE);
char nextp[] = { 'a','d','c' };//产品
srand(time(0) + rand());
int k = (rand() % 3); //随机生产其中一种产品
buffer[in] = nextp[k];
cout << "【1】生产者在缓冲区" << in << "加入产品" << buffer[in] << endl;
showBuffer(); //加入产品之后显示整个缓冲区情况
cout << endl;
in = (in + 1) % BUFFER_SIZE; //循环
Sleep(100);
ReleaseSemaphore(Full,1,NULL);
ReleaseMutex(Mutex);
} while (true);
}
//消费者
DWORD WINAPI Consumer(LPVOID)
{
do
{
WaitForSingleObject(Full, INFINITE);
WaitForSingleObject(Mutex, INFINITE);
cout << "【2】消费者在缓冲区消费第" << out << "个产品" << buffer[out] << endl;
//已消费产品为空,标记为“*”
buffer[out] = '*';
//缓冲区情况
showBuffer();
cout << endl;
out = (out + 1) % BUFFER_SIZE;
Sleep(100);
ReleaseSemaphore(Empty,1,NULL);
ReleaseMutex(Mutex);
} while (true);
}
int main()
{
InitBuffer();
Mutex = CreateMutex(NULL, FALSE, NULL);
Full = CreateSemaphore(NULL,0,BUFFER_SIZE, (LPCWSTR)"full");
Empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE,(LPCWSTR)"empty");
HANDLE produceThread = CreateThread(NULL, 0, Producer, NULL, 0, NULL);
HANDLE consumerThread = CreateThread(NULL, 0, Consumer, NULL, 0, NULL);
Sleep(INFINITE);
CloseHandle(Empty);//关闭句柄
CloseHandle(Full);
CloseHandle(Mutex);
CloseHandle(produceThread);
CloseHandle(produceThread);
}
运行结果
感谢指导!
(转载请注明)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)