Windows API一日一練(60)CreateIoCompletionPort和GetQueuedCompletionStatus函數

來源:互聯網
上載者:User

在Windows系統裡,使用完成連接埠是高效能的方法之一,比如把完成連接埠使用到線程池和網路伺服器裡。現在就通過線程池的方法來介紹怎麼樣使用完成連接埠,高效能的伺服器以後再仔細地介紹怎麼樣構造它。其實完成連接埠是一個隊列,所有的線程都在等訊息出現,如果隊列裡有訊息,就每個線程去擷取一個訊息執行它。先用函數CreateIoCompletionPort來建立一個訊息佇列,然後使用GetQueuedCompletionStatus函數來從隊列擷取訊息,使用函數PostQueuedCompletionStatus來向隊列裡發送訊息。通過這三個函數就實現完成連接埠的訊息迴圈處理。
 
函數CreateIoCompletionPort、GetQueuedCompletionStatus、PostQueuedCompletionStatus聲明如下:
 
WINBASEAPI
__out
HANDLE
WINAPI
CreateIoCompletionPort(
    __in     HANDLE FileHandle,
    __in_opt HANDLE ExistingCompletionPort,
    __in     ULONG_PTR CompletionKey,
    __in     DWORD NumberOfConcurrentThreads
    );
WINBASEAPI
BOOL
WINAPI
GetQueuedCompletionStatus(
    __in HANDLE CompletionPort,
    __out LPDWORD lpNumberOfBytesTransferred,
    __out PULONG_PTR lpCompletionKey,
    __out LPOVERLAPPED *lpOverlapped,
    __in DWORD dwMilliseconds
    );
 
WINBASEAPI
BOOL
WINAPI
PostQueuedCompletionStatus(
    __in     HANDLE CompletionPort,
    __in     DWORD dwNumberOfBytesTransferred,
    __in     ULONG_PTR dwCompletionKey,
    __in_opt LPOVERLAPPED lpOverlapped
    );
FileHandle是關聯的檔案控制代碼。
ExistingCompletionPort是已經存在的完成連接埠。
CompletionKey是傳送給處理函數的參數。
NumberOfConcurrentThreads是有多少個線程在訪問這個訊息佇列。
CompletionPort是已經存在的完成連接埠。
lpCompletionKey是傳送給處理函數的參數。
lpOverlapped是傳送給處理函數的參數。
dwMilliseconds是等待時間。
dwNumberOfBytesTransferred是傳送了多少個位元組。
 
調用函數的例子如下:
#001 #pragma once
#002
#003 #include "Thread.h"
#004
#005
#006 //使用IOCP實現線程池。
#007 //蔡軍生 2007/10/29 QQ:9073204 深圳
#008 class CThreadPools
#009 {
#010 public:
#011
#012  CThreadPools(void)
#013  {
#014          m_nThreadCount = 2;
#015   }
#016
#017  ~CThreadPools(void)
#018  {
#019  }
#020
#021  bool Init(void)
#022  {
#023         //建立一個IOCP。
#024         m_hQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, m_nThreadCount);
#025         if (m_hQueue == NULL)
#026         {
#027               //建立IOCP失敗。
#028               return false;
#029         }
#030  }
#031
#032  int GetThreadCount(void) const
#033  {
#034         return m_nThreadCount;
#035  }
#036
#037  //線程池處理的內容。
#038  DWORD Run(void)
#039  {
#040         DWORD dwBytesTransfered;
#041         ULONG_PTR dwCompletionKey;
#042
#043         OVERLAPPED* pOverlapped;
#044
#045         //等一個IOCP的訊息。
#046        while (GetQueuedCompletionStatus(m_hQueue, &dwBytesTransfered, &dwCompletionKey, &pOverlapped, INFINITE))
#047         {
#048               if (pOverlapped == ((OVERLAPPED*) ((__int64) -1)) )
#049               {
#050                    //退出。
#051                    OutputDebugString(_T("退出 \r\n"));
#052                    break;
#053               }
#054               else                                            
#055        
#056               {
#057                    WPARAM request = (WPARAM) dwCompletionKey;
#058
#059                    //處理訊息。
#060                    OutputDebugString(_T("GetQueuedCompletionStatus \r\n"));
#061               }
#062         }
#063
#064         return 0;
#065  }
#066
#067  //發送處理的訊息。
#068  bool QueueRequest(WPARAM wParam)
#069  {        
#070         //往IOCP裡發送一條訊息。
#071        if (!PostQueuedCompletionStatus(m_hQueue, 0, (ULONG_PTR) wParam, NULL))
#072         {
#073               return false;
#074         }
#075        
#076         return true;
#077  }
#078
#079  //關閉所有線程。
#080  void Close(void)
#081  {
#082         for (int i = 0; i < m_nThreadCount; i++)
#083         {
#084               PostQueuedCompletionStatus(m_hQueue, 0, 0, (OVERLAPPED*) ((__int64) -1) );
#085         }
#086  }
#087
#088 protected:
#089  //接收訊息處理的隊列。
#090  HANDLE m_hQueue;
#091
#092  //線程個數。
#093  int m_nThreadCount;
#094 };
#095
#096 //////////////////////////////////////////////////////////////////////////
#097 class CThreads :
#098  public CThread
#099 {
#100 public:
#101  CThreads(CThreadPools* pPool)
#102  {
#103          m_pPool = pPool;        
#104  }
#105  virtual ~CThreads(void)
#106  {
#107
#108  }
#109
#110
#111 protected:
#112  //
#113  //線程運行函數。
#114  //在這裡可以使用類裡的成員,也可以讓衍生類別實現更強大的功能。
#115  //蔡軍生 2007/10/29
#116  virtual DWORD Run(void)
#117  {
#118         //
#119         if (m_pPool)
#120         {
#121               return m_pPool->Run();
#122         }
#123
#124         return -1;
#125  }
#126
#127 protected:
#128  CThreadPools* m_pPool;
#129
#130 };

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/caimouse/archive/2007/10/29/1855142.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.