window下简单的生产者和单一消费的程序

window下简单的生产者和单一消费的程序

使用window下的事件和临界区实现,

在Linux可以使用条件变量和互斥锁实现,

简单的代码如下:

#ifndef _MSGQUEUE_
#define _MSGQUEUE_
///
//消息队列节点
//
#include <Windows.h>

#define MY_X_LOCK(x) EnterCriticalSection(x)
#define MY_X_UNLOCK(x) LeaveCriticalSection(x)
#define MY_X_LOCK_INIT(x) InitializeCriticalSection(x)
#define MY_X_LOCK_DEINIT(x) DeleteCriticalSection(x)
#define MY_COND_WIAT( XHanle , block_time_ms ) WaitForSingleObject(XHanle , block_time_ms)
#define MY_COND_CREATE() CreateEvent(NULL,TRUE,FALSE, NULL)
#define MY_COND_SEND(x) SetEvent(x)
#define MY_COND_DESTROY(x) CloseHandle(x)
//
//使用指针传参
//
template <typename Object>
class MSGQueue {
public:
	
	MSGQueue(int size):theSize(size){ init(); }
	~MSGQueue(){ clear(); }

	/*
	*push data to queue
	*/
	void push( Object& x)
	{
		//::pthread_mutex_lock(&m_pushLock); //for linux
		
		//printf(" push ---->>>>(%#x) \n",(long)workqWp);
		
		MY_X_LOCK(&m_wlock);

		//MY_X_LOCK(&workqWp->qlock);
		
		//保护临界资源
		if(workqWp->writable ){
			workqWp->data = x;

			workqWp->writable = 0x00;

			//MY_X_UNLOCK(&workqWp->qlock);

			MY_COND_SEND(workqWp->qready);

			workqWp = workqWp->next;
		}
		else {
			printf("buffer full \n");
		}
		
		MY_X_UNLOCK(&m_wlock);
	}

	/*
	*add by lqh
	*block_time_ms : unit is ms.
	*/
	int front(Object& x, long block_time_ms)
	{
		int ret = -1;

		//MY_X_LOCK(&workqRp->qlock);

		if(workqRp->writable) 
		{
			if ( block_time_ms < 0 ) {	

				MY_COND_WIAT(workqRp->qready ,INFINITE);
				ResetEvent(workqRp->qready);//重置为无信号状态
				if ( !workqRp->writable ) {
				 	x = workqRp->data;
					workqRp->writable = 0x01;
					ret = 0;
				}

				//MY_X_UNLOCK(&workqRp->qlock);

				if(ret == 0 ){
					workqRp = workqRp->next;
				}
				return ret;
			}
			else{
                //
				//等待信号被触发 阻塞等待,超时时间 block_time_ms 毫秒
                //
				if(MY_COND_WIAT(workqRp->qready, block_time_ms) != WAIT_OBJECT_0) {
					ResetEvent(workqRp->qready);//重置为无信号状态
					//printf("unlock timeout \n");
					//MY_X_UNLOCK(&workqRp->qlock);
					return -1;
				}else {
					//printf("fffff->\n");
					ResetEvent(workqRp->qready);//重置为无信号状态
					//
					//此时workqRp->qlock 已经被释放了
					//
					if ( !workqRp->writable ) {
					 	x = workqRp->data;
						workqRp->writable = 0x01;
						ret = 0;
					}

					//MY_X_UNLOCK(&workqRp->qlock);
					
					if(ret == 0 ){
						workqRp = workqRp->next;
					}
					return ret;
				}
			}
		}
		else {

			if ( !workqRp->writable ) {
				 x = workqRp->data;
				workqRp->writable = 0x01;
				ret = 0;
			}


			//MY_X_UNLOCK(&workqRp->qlock);

			if(ret == 0 ){
				workqRp = workqRp->next;
			}
		}

		return ret;
	}

	
private:

	void init()
	{
		int i =0;
		Node* temp;

		workq = static_cast<struct Node*>(::malloc( sizeof(struct Node) * theSize ));
		/*
		*create a rink buffer !
		*/
	
		temp = workq;
		do{
			
			temp->writable = 0x01;
			temp->qready = MY_COND_CREATE();
			//MY_X_LOCK_INIT (&temp->qlock);
			if(i == (theSize - 1)){
				temp->next = workq;
			}
			else{
				temp->next = (Node*)((char*)temp + sizeof(Node));
				temp = temp->next;
			}
            i ++;
		}while( i < theSize);

		workqRp = workq;
		workqWp = workq;
		MY_X_LOCK_INIT(&m_wlock);
	}
	
	void clear()
	{ 
		Node* temp = workq->next;
		while(workq != temp) {
			MY_X_LOCK_DEINIT(&temp->qlock);
			MY_COND_DESTROY(temp->qready);
			temp = temp->next;
		}
		free(workq);
		MY_X_LOCK_DEINIT(&m_wlock);
	}

private:
	struct Node{
		Object data;
		HANDLE  qready;//
		//CRITICAL_SECTION qlock;                  // mutex
		int writable;
		Node* next;
		Node(const Object& d = Object() ,  Node* n = NULL):data(d) ,next(n) ,writable(1){}
	};

	int theSize;
	Node *workq  ;
	Node *workqRp ;
	Node *workqWp ;
	
	CRITICAL_SECTION m_wlock;

};

#endif

 下面是测试子程序

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

#include "stdafx.h"
#include "msgQueue.h" 
//
//
CRITICAL_SECTION wlock;
int i = 1;
typedef struct {
	int _conut;
	char _string[128];
}messageNode;

class message{
public:
	message(){m_message = NULL;}
	~message(){if(m_message) free(m_message);}
	void* GetMessage(){return m_message;}
	void ResetMessage(int len) {
		if(m_message) free(m_message);
		m_message = (void*)malloc(len);
		memset(m_message, 0, len);
	}
private:
	void* m_message;
	int len;
};



DWORD WINAPI MYProducerThread(LPVOID);
DWORD WINAPI MYConsumerThread(LPVOID);

int _tmain(int argc, _TCHAR* argv[])
{	
	InitializeCriticalSection(&wlock);
	HANDLE handle[3];
	MSGQueue<message*>* g_msgQueue = new MSGQueue<message*>(10); //多线程共享该队列
	handle[0] = CreateThread(NULL, 0, MYProducerThread, g_msgQueue, 0, NULL);	//生产者线程1
	handle[1] = CreateThread(NULL, 0, MYProducerThread, g_msgQueue, 0, NULL);	//生产者线程2
	handle[2] = CreateThread(NULL, 0, MYConsumerThread, g_msgQueue, 0, NULL);		//消费者线程3
	while(1){
		Sleep(1000);
	}
	return 0;
}
DWORD WINAPI MYProducerThread(LPVOID param)
{
		MSGQueue<message*>* g_msgQueue = (MSGQueue<message*>*)param;

		while(1) {
			MY_X_LOCK(&wlock);
			message* msg = new message();
			messageNode* messageData;
			msg->ResetMessage(sizeof(messageNode));
			messageData = (messageNode*)msg->GetMessage();
			messageData->_conut = i++;
			sprintf(messageData->_string,"this 第 %d 生产 ",messageData->_conut);
			printf("producer: %d, %s \n", messageData->_conut, messageData->_string);
			g_msgQueue->push(msg);
			MY_X_UNLOCK(&wlock);
			//g_msgQueue->push()
			Sleep(100);

	}
}

DWORD WINAPI MYConsumerThread(LPVOID param)
{
	MSGQueue<message*>* g_msgQueue = (MSGQueue<message*>*)param;
	int i = 1;
	while(1) {
		message* msg;
		if(g_msgQueue->front( msg,50) == 0) {
			messageNode* messageData;
			messageData = (messageNode*)msg->GetMessage();
			printf("%d, %s \n", messageData->_conut, messageData->_string);
			delete msg;
		}
		else {
			printf("time out \n");
		}

	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

john_liqinghan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值