在Windows系统里使用完成端口

来源:互联网 发布:淘宝助理批量编辑 编辑:程序博客网 时间:2024/06/07 21:07
    在Windows系统里,使用完成端口高性能的方法之一,比如把完成端口使用到线程池和网络服务器里。现在就通过线程池的方法来介绍怎么样使用完成端口,高性能的服务器以后再仔细地介绍怎么样构造它。其实完成端口一个队列,所有的线程都在等消息出现,如果队列里有消息,就每个线程去获取一个消息执行它。先用函数CreateIoCompletionPort来创建一个消息队列,然后使用GetQueuedCompletionStatus函数来从队列获取消息,使用函数PostQueuedCompletionStatus来向队列里发送消息。通过这三个函数就实现完成端口的消息循环处理。


HANDLE CreateIoCompletionPort(
    HANDLE FileHandle,//关联的文件句柄
    HANDLE ExistingCompletionPort,//已经存在的完成端口
    ULONG_PTR CompletionKey,//传送给处理函数的参数
    DWORD NumberOfConcurrentThreads//有多少个线程在访问这个消息队列
    );


BOOL GetQueuedCompletionStatus(
    HANDLE CompletionPort,//已经存在的完成端口
    LPDWORD lpNumberOfBytesTransferred,
    PULONG_PTR lpCompletionKey,//传送给处理函数的参数
    LPOVERLAPPED *lpOverlapped,//传送给处理函数的参数
    DWORD dwMilliseconds//等待时间
    );


BOOL PostQueuedCompletionStatus(
    HANDLE CompletionPort,
    DWORD dwNumberOfBytesTransferred,//传送了多少个字节
    ULONG_PTR dwCompletionKey,
    LPOVERLAPPED lpOverlapped
    );


//调用函数的例子如下:
#pragma once
#include "Thread.h"


//使用IOCP实现线程池。
class CThreadPools
{
public:
CThreadPools(void)
{
m_nThreadCount = 2;
}


bool Init(void)
{
//创建一个IOCP。
m_hQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, m_nThreadCount);
if (m_hQueue == NULL)
{
//创建IOCP失败。
return false;
}
}


int GetThreadCount(void) const
{
return m_nThreadCount;
}


//线程池处理的内容。
DWORD Run(void)
{
DWORD dwBytesTransfered;
ULONG_PTR dwCompletionKey;
OVERLAPPED* pOverlapped;


//等一个IOCP的消息。
while (GetQueuedCompletionStatus(m_hQueue, &dwBytesTransfered, &dwCompletionKey, &pOverlapped, INFINITE))
{
if (pOverlapped == ((OVERLAPPED*)((__int64)-1)))
{
//退出。
OutputDebugString(_T("退出 /r/n"));
break;
}else{
WPARAM request = (WPARAM) dwCompletionKey;
//处理消息。
OutputDebugString(_T("GetQueuedCompletionStatus /r/n"));
}
}
return 0;
}


//发送处理的消息。
bool QueueRequest(WPARAM wParam)
{        
//往IOCP里发送一条消息。
if (!PostQueuedCompletionStatus(m_hQueue, 0, (ULONG_PTR) wParam, NULL))
return false;
return true;
}


//关闭所有线程。
void Close(void)
{
for (int i = 0; i < m_nThreadCount; i++)
PostQueuedCompletionStatus(m_hQueue, 0, 0, (OVERLAPPED*) ((__int64) -1) );
}


protected:
//接收消息处理的队列。
HANDLE m_hQueue;
//线程个数。
int m_nThreadCount;
};


class CThreads : public CThread
{
public:
CThreads(CThreadPools* pPool)
{
m_pPool = pPool;        
}


protected:
//线程运行函数。
//在这里可以使用类里的成员,也可以让派生类实现更强大的功能。
virtual DWORD Run(void)
{
if (m_pPool)
return m_pPool->Run();
return -1;
}


protected:
CThreadPools* m_pPool;
};



原创粉丝点击