生产者消费者问题

生产者消费者问题是操作系统非常经典的一个问题,

问题描述:考虑有一些生产者和消费者进程,生产者进程生产信息并把它们放入缓冲池中,消费者从缓冲池中取走信息。生产者—消费者问题是相互合作的进程关系的一种抽象,如在输入时,输入进程是生产者,计算进程是消费者;而在输出时,则计算进程是生产者,打印进程是消费者。请使用信号量机制来解决生产者—消费者问题。

生产者消费者问题的重点是:

1生产者只有在缓冲池有空的时候才能去填充,否则只能等待

2消费者只有在缓冲池中有数据的时候才能消费数据,否则只能等待。

3由于存在多个生产者消费者线程,为了不产生幽灵数据,对缓冲池的操作必须是互斥的

4 生产者和消费者线程中的P V操作的顺序必须慎重考虑,否则会产生死锁

windows 提供了常用的互斥量(mutex)和信号量(Semaphore)两种数据结构

常用的操作有CreateSemaphore()、OpenSemaphore()、ReleaseSemaphore()、WaitForSingleObject()和WaitForMultipleObjects()等函数

CreateSemaphore()用来生成信号量可以指明信号量的大小初始值

WaitForSingleObject()用于消费信号量使得信号量减一

ReleaseSemaphore()将是信号量加一(可指定)

对于互斥量的操作也有一组操作

CreateMutex()生成一个互斥量

WaitForSingleObject()等待互斥量

ReleaseMutex()释放互斥量

生产者消费者的示例程序如下

// procom.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<Windows.h>
using namespace std;

const int BUFFER_SIZE = 5;
const int producerCount = 10;
const int consumerCount = 10;
const int timewait = INFINITE;
static int pID = 0;
int cID = 0;
HANDLE mutex;
HANDLE empty;
HANDLE full;
int in =0,out=0;
int buffer[BUFFER_SIZE];

DWORD WINAPI pFunc(LPVOID lparam);
DWORD WINAPI cFunc(LPVOID lparam);

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE pThread[producerCount];
	HANDLE cThread[consumerCount];
	DWORD producerID[producerCount];
	DWORD consumerID[consumerCount];

	mutex = CreateMutex(NULL,FALSE,NULL);
	empty = CreateSemaphore(NULL,BUFFER_SIZE,BUFFER_SIZE,NULL);
	full = CreateSemaphore(NULL,0,BUFFER_SIZE,NULL);

	for(int i =0;i<producerCount;++i)
	{
		pThread[i] = CreateThread(NULL,0,pFunc,NULL,0,&producerID[i]);
		if(NULL == pThread[i])
		{
			return -1;
		}
	}

	for(int i=0;i<consumerCount;i++)
	{
		cThread[i] = CreateThread(NULL,0,cFunc,NULL,0,&consumerID[i]);
		if(NULL ==cThread[i])
			return -1;
	}

	int a;
	cin>>a;
	for(int i=0;i<producerCount;i++)
		CloseHandle(pThread[i]);
	for (int i=0;i<consumerCount;i++)
		CloseHandle(cThread[i]);
	CloseHandle(mutex);
	CloseHandle(full);
	CloseHandle(empty);
	return 0;
}

DWORD WINAPI pFunc(LPVOID lparam)
{
	Sleep(100);
	WaitForSingleObject(empty,timewait);
	WaitForSingleObject(mutex,timewait);
	
	cout<<"produced by :"<<pID<<"in buffer  pos " <<in<<endl;
	buffer[in]=pID;
	pID++;
	in = (in +1)%BUFFER_SIZE;
	ReleaseMutex(mutex);
	ReleaseSemaphore(full,1,NULL);
	return 0;
}
DWORD WINAPI cFunc(LPVOID lparam)
{
	Sleep(100);
	WaitForSingleObject(full,timewait);
	WaitForSingleObject(mutex,timewait);
	cID=buffer[out];
   
	 cout<<"consumed one ID:"<<cID<< " on buffer pos "<<out<<endl;
	   out=(out+1)%BUFFER_SIZE;
	ReleaseMutex(mutex);
	ReleaseSemaphore(empty,1,NULL);
	return 0;
}

本文的程序以及概念参考如下

http://blog.csdn.net/wangweitingaabbcc/article/details/6833265
http://www.cnblogs.com/P_Chou/archive/2012/07/13/semaphore-and-mutex-in-thread-sync.html
http://blog.chinaunix.net/uid-26779539-id-3233615.html



转载于:https://my.oschina.net/u/2322146/blog/406224

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值