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 };  
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.