相關UML如下:

添加:

處理

關鍵代碼解析:
1
//開始服務
2
bool __cdecl CQueueService::StartService()
3

{
4
//效驗參數
5
ASSERT(m_bService==false);
6
ASSERT(m_hCompletionPort==NULL);
7
ASSERT(m_pIQueueServiceSink!=NULL);
8
9
//建立完成端口
10
//! 需要追蹤一下這里的完成端口句柄
11
//! 首先分析這里的創建,INVALID_HANDLE_VALUE表示沒有關聯任何文件句柄,也就是
12
//! 說不存在某個實現某個操作完成以后系統自動給這個完成端口post一個完成消息的概念
13
//! 然后這里用限制工作線程數是1,也就是同意時刻只會有一條線程受到完成消息
14
m_hCompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,1);
15
if (m_hCompletionPort==NULL) throw TEXT("隊列對象完成端口創建失敗");
16
17
//啟動線程
18
if (m_QueueServiceThread.InitThread(m_hCompletionPort)==false) throw TEXT("隊列對象線程初始化失敗");
19
if (m_QueueServiceThread.StartThead()==false) throw TEXT("隊列對象線程啟動失敗");
20
21
//設置參數
22
m_bService=true;
23
24
return true;
25
}
m_QueueServiceThread.InitThread(m_hCompletionPort);
他悄悄的給完成端口句柄扔給了服務線程,偶們去看看服務線程拿這玩意干了啥,,,
//運行函數
bool CQueueServiceThread::RepetitionRun()


{
//效驗參數
ASSERT(m_hCompletionPort!=NULL);

//變量定義
DWORD dwThancferred=0;
OVERLAPPED * pOverLapped=NULL;
CQueueService * pQueueService=NULL;

//等待完成端口
if (GetQueuedCompletionStatus(m_hCompletionPort,&dwThancferred,(PULONG_PTR)&pQueueService,&pOverLapped,INFINITE))

{
//判斷退出
if (pQueueService==NULL) return false;

//獲取數據
tagDataHead DataHead;
bool bSuccess=pQueueService->GetData(DataHead,m_cbBuffer,sizeof(m_cbBuffer));
ASSERT(bSuccess==true);

//處理數據
if (bSuccess==true) pQueueService->OnQueueServiceThread(DataHead,m_cbBuffer,DataHead.wDataSize);

return true;
}

return false;
}
秘密在此:
GetQueuedCompletionStatus(m_hCompletionPort,&dwThancferred,(PULONG_PTR)&pQueueService,&pOverLapped,INFINITE)
m_hCompletionPort是通過線程參數傳遞進來的,dwThancferred和pQueueService是在之前CQueueService::AddToQueue()中Post過來的參數,,,
//加入數據
bool __cdecl CQueueService::AddToQueue(WORD wIdentifier, void * const pBuffer, WORD wDataSize)


{
CThreadLockHandle LockHandle(&m_ThreadLock);
m_DataStorage.AddData(wIdentifier,pBuffer,wDataSize);
PostQueuedCompletionStatus(m_hCompletionPort,wDataSize,(ULONG_PTR)this,NULL);
return true;
}
數據經過完成端口在CQueueServiceThread繞一圈以后會回到CQueueService::OnQueueServiceThread()
//數據消息
void CQueueService::OnQueueServiceThread(const tagDataHead & DataHead, void * pBuffer, WORD wDataSize)


{
ASSERT(m_pIQueueServiceSink!=NULL);
try

{
m_pIQueueServiceSink->OnQueueServiceSink(DataHead.wIdentifier,pBuffer,DataHead.wDataSize,DataHead.dwInsertTime);
}

catch (
)
{}
return;
}
這樣隊列服務就完成了他的使命,將執行的消息,異步的交給指定接口去處理,,,
稍后將對列隊列服務做個宏觀上的的分析,,,下班時間到,,,回去繼續,,,
用一句話來描述QueueService模塊就是:
將隊列的插入和處理通過關聯到完成端口上以實現在IOCP線程池管理下異步處理;
Add以后投遞完成消息,在完成端口上監聽的線程受到消息以后讀取數據并處理;