线程安全的队列

设计方式

template<class T>
class CWTQueue{
public:
    //定义枚举类型,说明队列所做的操作
    enum{
		WQNone,
		WQPush,
		WQPop,
		WQSize,
		WQClear
	};
    //该结构体只属于类内部使用,用于向IOCP投递信息
    typedef struct IocpParam {
		IocpParam(int op, const T& sData, HANDLE hEve = NULL)
			:nOperator(op), Data(sData), hEvent(hEve) {}
		IocpParam() :nOperator(WQNone) {}

		size_t	nOperator;	//操作
		T		Data;		//数据
		HANDLE	hEvent;		//pop 操作需要的
	}PPARAM;
 public://定义类主体函数
    CWTQueue();
	virtual bool PopFront(T& data);
	bool	PushBack(const T& data);
	bool	Clear();
	size_t	Size();
	virtual ~CWTQueue();
protected://声明线程函数体
    static  void threadEntry(void* arg);		//对外封装接口 
	virtual void DealParam(PPARAM* pParam);		//消息处理函数
			void threadMain();					//线程主体函数
protected:	
    std::list<T>		m_lstData;				//内部维护的链表,存储信息
	HANDLE				m_hCompletetionPort;	//iocp句柄
	HANDLE				m_hThread;				//线程接口
	std::atomic<bool>	m_lock;					//原子类型
};
template<class T>
inline CWTQueue<T>::CWTQueue(){
    //最后一个参数表示能够同时访问队列的线程数
	//参数一:代表一个句柄,如果是做文件,可以是文件句柄,如果是做串口,可以做串口句柄
	//参数二:代表已经存在的完成端口句柄
	//参数三:代表Key
	m_hCompletetionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1);
	m_hThread = INVALID_HANDLE_VALUE;
	if (m_hCompletetionPort != NULL) {
        //开启处理IOCP消息的线程函数
		m_hThread = (HANDLE)_beginthread(&CWTQueue::threadEntry, 0, this);
	}
}

template<class T>
inline bool CWTQueue<T>::PushBack(const T& data){
	IocpParam* pParam = new IocpParam(WQPush, data);//创建投递的信息
	if (m_lock == true) {//通过该原子类型决定并发安全
		delete pParam;
		return false;
	}
    //投递信息
	bool ret = PostQueuedCompletionStatus(m_hCompletetionPort, sizeof(PPARAM), (ULONG_PTR)pParam, NULL);
	if (ret == false)delete pParam;
	//printf("push back done %d %08p\r\n", ret, (void*)pParam);
	return ret;
}

template<class T>
inline bool CWTQueue<T>::PopFront(T& data){
	HANDLE	hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//创建事件
	IocpParam pParam(WQPop, data, hEvent);
	if (m_lock) {
		if (hEvent)CloseHandle(hEvent);
		return false;
	}
    //投递信息
	bool ret = PostQueuedCompletionStatus(m_hCompletetionPort, sizeof(PPARAM), (ULONG_PTR)&pParam, NULL);
	if (ret == false) {
		CloseHandle(hEvent);
		return false;
	}
    //等待事件暂停
	ret = WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0;
	if (ret) data = pParam.Data;
	return ret;
}

template<class T>
inline size_t CWTQueue<T>::Size(){
	HANDLE	hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	IocpParam pParam(WQSize, T(), hEvent);
	if (m_lock) {
		if(hEvent)CloseHandle(hEvent);
		return -1;
	}
	bool ret = PostQueuedCompletionStatus(m_hCompletetionPort, sizeof(PPARAM), (ULONG_PTR)&pParam, NULL);
	if (ret == false) {
		CloseHandle(hEvent);
		return -1;
	}
	ret = WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0;
	if (ret) return pParam.nOperator;
	return ret;
}

template<class T>
inline bool CWTQueue<T>::Clear()
{
	if (m_lock == true)return false;
	IocpParam* pParam = new IocpParam(WQClear, T());
	bool ret = PostQueuedCompletionStatus(m_hCompletetionPort, sizeof(PPARAM), (ULONG_PTR)pParam, NULL);
	if (ret == false)delete pParam;
	//printf("Clear %08p\r\n", (void*)pParam);
	return true;
}

template<class T>
inline CWTQueue<T>::~CWTQueue(){
	if (m_lock)return;
	m_lock = true;
	PostQueuedCompletionStatus(m_hCompletetionPort, 0, NULL, NULL);
	WaitForSingleObject(m_hThread, INFINITE);
	//防御性编程先置空 在释放
	if (m_hCompletetionPort != NULL) {
		HANDLE hTemp = m_hCompletetionPort;
		m_hCompletetionPort = NULL;
		CloseHandle(hTemp);
	}
}
posted @ 2024-01-23 18:59  孟秋十三  阅读(10)  评论(0)    收藏  举报