设计方式
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);
}
}