windows多线程多缓冲区单生产者多消费者

前几天读了一篇文章,介绍线程同步的。讲到但生产者多消费者的时候,运用了一个例子文章的博客地址:

http://blog.csdn.net/morewindows/article/details/7577591

我个人不是很理解,当一个读线程和两个写线程同时使用一个临界区时,多缓冲区的作用从何而来。个人认为多缓冲区绝对不可以对线程进行加锁,尤其是互斥锁Mutex

和CriticalSection。锁还是要加,我认为应该加到缓冲区上,如果你有十个缓冲区,那么你就给这个工程陪十个锁。每个缓冲区一个,但是绝不相同。缓冲区要设计成类

读和写分别加锁。这样无论多少个消费者,都可以拿数据。消费者可以任意增加!

我的水平有限,以上只是我的意见,我并不能确定一定对。希望高人指教

</pre><pre name="code" class="html">// MutiThreadBuffer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
//1生产者 2消费者 4缓冲区
#include <stdio.h>
#include <process.h>
#include <windows.h>
//设置控制台输出颜色
#include "LockFreeRingQueue.h"


const int END_PRODUCE_NUMBER = 100;  //生产产品个数
const int BUFFER_SIZE = 4;          //缓冲区个数
CLockFreeRingQueue oCLockFreeRingQueue(BUFFER_SIZE);
HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull;
//生产者线程函数
unsigned int __stdcall ProducerThreadFun(PVOID pM)
{
	for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
	{
		//等待有空的缓冲区出现
		WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE);

		oCLockFreeRingQueue.insertData(&i);
		ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);
	}
	printf("生产者完成任务,线程结束运行\n");
	return 0;
}
//消费者线程函数
unsigned int __stdcall ConsumerThreadFun_1(PVOID pM)
{
	int iGetData = 0;
	while (true)
	{
		//等待非空的缓冲区出现
		WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);

		oCLockFreeRingQueue.getData(&iGetData); //实际项目中此处获得数据的内存建议用深拷贝
		//Sleep(50); //some other work to do

		ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);
	}

	return 0;
}

unsigned int __stdcall ConsumerThreadFun_2(PVOID pM)
{
	int iGetData = 0;
	while (true)
	{
		//等待非空的缓冲区出现
		WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE);
		oCLockFreeRingQueue.getData(&iGetData);
		//Sleep(50); //some other work to do

		ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL);
	}

	return 0;
}
int main()
{
	printf("  生产者消费者问题   1生产者 2消费者 4缓冲区\n");
	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

	//初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数.
	g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL);
	g_hSemaphoreBufferFull  = CreateSemaphore(NULL, 0, 4, NULL);
	
	const int THREADNUM = 3;
	HANDLE hThread[THREADNUM];
	//生产者线程
	hThread[0] = (HANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL);
	//消费者线程
	hThread[1] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun_1, NULL, 0, NULL);
	hThread[2] = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun_2, NULL, 0, NULL);
	WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE);
	for (int i = 0; i < THREADNUM; i++)
		CloseHandle(hThread[i]);

	//销毁信号量和关键段
	CloseHandle(g_hSemaphoreBufferEmpty);
	CloseHandle(g_hSemaphoreBufferFull);

	return 0;
}

#include "stdafx.h"
#include "LockFreeRingQueue.h"
#include <process.h>
BOOL SetConsoleColor(WORD wAttributes)
{
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (hConsole == INVALID_HANDLE_VALUE)
		return FALSE;

	return SetConsoleTextAttribute(hConsole, wAttributes);
}
bool CLockFreeRingQueue::insertData(int *pInData)
{
	EnterCriticalSection(&m_gs);
	size_t iNextIndex = (m_iWriteIndex + 1) % m_iBufferSize;
	if (iNextIndex == m_iReadIndex) 
	{
		LeaveCriticalSection(&m_gs);
		return false;
	} 
	else 
	{
		m_iData[m_iWriteIndex] = *pInData;
		std::cout<<"生产者在缓冲池第"<<m_iWriteIndex<<"个缓冲区中投放数据"<<*pInData<<std::endl;
		m_iWriteIndex = iNextIndex;
		LeaveCriticalSection(&m_gs);
		return true;
	}

}

bool CLockFreeRingQueue::getData(int *pOutData)
{
	EnterCriticalSection(&m_gs);
	if (m_iReadIndex == m_iWriteIndex) 
	{
		LeaveCriticalSection(&m_gs);
		return false;
	}
	else 
	{
		
		*pOutData = m_iData[m_iReadIndex];
		SetConsoleColor(FOREGROUND_GREEN);
		std::cout<<"编号为"<<GetCurrentThreadId()<<"的消费者从缓冲池中第"<<m_iReadIndex<<"个缓冲区中投放数据"<<*pOutData <<std::endl;
		SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
		m_iReadIndex = (m_iReadIndex + 1) % m_iBufferSize;
	    LeaveCriticalSection(&m_gs);
		return true;
	}
}

#ifndef _LOCKFREERINGQUEUE_H_
#define _LOCKFREERINGQUEUE_H_
#include <Windows.h>
#include <iostream>
class CLockFreeRingQueue 
{
public:
	CLockFreeRingQueue(const size_t &size) : m_iBufferSize(size + 1), m_iReadIndex(0), m_iWriteIndex(0) 
	{
		m_iData = new int[size];
		InitializeCriticalSection(&m_gs);
	}
	~CLockFreeRingQueue()
	{
	}
	bool insertData(int *pInData);
	bool getData(int *pOutData);

private:

	size_t m_iReadIndex;
	size_t m_iWriteIndex;
	size_t m_iBufferSize;
public:
	int *m_iData;
	CRITICAL_SECTION m_gs;

};

#endif
这个例子比较粗糙,我只是测试了一下,应该可以拿来用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值