网狐棋牌(一) ServerKernel中的IQueueService接口分析
相關UML如下:
添加:
處理
關鍵代碼解析:
?1//開始服務
?2bool?__cdecl?CQueueService::StartService()
?3{
?4????//效驗參數(shù)
?5????ASSERT(m_bService==false);
?6????ASSERT(m_hCompletionPort==NULL);
?7????ASSERT(m_pIQueueServiceSink!=NULL);
?8
?9????//建立完成端口
10????//!?需要追蹤一下這里的完成端口句柄
11????//!?首先分析這里的創(chuàng)建,INVALID_HANDLE_VALUE表示沒有關聯(lián)任何文件句柄,也就是
12????//!?說不存在某個實現(xiàn)某個操作完成以后系統(tǒng)自動給這個完成端口post一個完成消息的概念
13????//!?然后這里用限制工作線程數(shù)是1,也就是同意時刻只會有一條線程受到完成消息
14????m_hCompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,1);
15????if?(m_hCompletionPort==NULL)?throw?TEXT("隊列對象完成端口創(chuàng)建失敗");
16
17????//啟動線程
18????if?(m_QueueServiceThread.InitThread(m_hCompletionPort)==false)?throw?TEXT("隊列對象線程初始化失敗");
19????if?(m_QueueServiceThread.StartThead()==false)?throw?TEXT("隊列對象線程啟動失敗");
20
21????//設置參數(shù)
22????m_bService=true;
23
24????return?true;
25}
m_QueueServiceThread.InitThread(m_hCompletionPort);
他悄悄的給完成端口句柄扔給了服務線程,偶們?nèi)タ纯捶站€程拿這玩意干了啥,,,
bool?CQueueServiceThread::RepetitionRun()
{
????//效驗參數(shù)
????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;
????????//獲取數(shù)據(jù)
????????tagDataHead?DataHead;
????????bool?bSuccess=pQueueService->GetData(DataHead,m_cbBuffer,sizeof(m_cbBuffer));
????????ASSERT(bSuccess==true);
????????//處理數(shù)據(jù)
????????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是通過線程參數(shù)傳遞進來的,dwThancferred和pQueueService是在之前CQueueService::AddToQueue()中Post過來的參數(shù),,,
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;
}
數(shù)據(jù)經(jīng)過完成端口在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;
}
這樣隊列服務就完成了他的使命,將執(zhí)行的消息,異步的交給指定接口去處理,,,
稍后將對列隊列服務做個宏觀上的的分析,,,下班時間到,,,回去繼續(xù),,,
用一句話來描述QueueService模塊就是:
將隊列的插入和處理通過關聯(lián)到完成端口上以實現(xiàn)在IOCP線程池管理下異步處理;
Add以后投遞完成消息,在完成端口上監(jiān)聽的線程受到消息以后讀取數(shù)據(jù)并處理;
總結
以上是生活随笔為你收集整理的网狐棋牌(一) ServerKernel中的IQueueService接口分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网狐棋牌游戏平台服务器架构设计分析
- 下一篇: 网狐棋牌(二) CQueueServic