Windows異步I/O和完成端口

作者: 大彭  發布時間: 2014-11-15 10:32  閱讀: 4445 次  推薦: 3   原文鏈接   [收藏]  

  上周做了一次關于Windows異步I/O和完成端口的部門技術分享,著重于理論介紹, 順帶review基于IOCP的網絡庫代碼。

  完成端口是異步I/O的一種,將這兩個并列作為標題,因為完成端口的復雜性及用途相比其他幾種異步I/O加起來還過之。Windows核心編程中關于設備異步I/O介紹的很明白,這里再回顧一下。

  先區分兩組概念:同步/異步(Async/Sync)阻塞/非阻塞(blocking/non-blocking)

  這兩組概念很曖昧,有時可以不用分的很清楚。我將這兩組概念分別定性為面向結果面向過程。想象生活中排隊的場景。印象中排隊最痛苦的是2010那年在上海觀看世博會,每進一個場館要排上2-5個小時,而且天氣燥熱,排隊過程中異常難耐。另外一種進場館的方式就是憑預約票,可以在當天按票上時間段進場。排隊進館就是一種同步方式,直到隊伍中輪到你才可以進去,憑票進館則是異步方式,兩種方式都是面向同一個結果:進館。但是排隊過程中,只能在隊伍中等待,意味著行為失去自由,也就是阻塞,什么事也做不了;而憑票則可以在進館之前到任何其他想去的地方,行動自由,也就是非阻塞的。從這個例子中可以看出為什么喜歡異步和非阻塞了,體現在程序中,則是它們的性能差別(可以看這篇)。現在開始介紹異步I/O。

  一、請求異步I/O的條件

  任何異步I/O都需要有系統設施的支撐,正如取票進館需要有預約票作憑證。請求異步I/O也需要兩個基本條件:隊列和重疊結構(OVERLAPPED,重疊是指I/O請求的時間和線程執行其他任務的時間是重疊的)。

typedef struct _OVERLAPPED { 
    ULONG_PTR Internal;        // I/O請求錯誤碼
    ULONG_PTR InternalHigh;    // 已傳輸字節數
    DWORD Offset;              // I/O操作位置(低、高位),非文件設備忽略
    DWORD OffsetHigh; 
    HANDLE hEvent;             // 內核事件對象或自定義結構
}OVERLAPPED;

  隊列由設備驅動程序維護,記錄I/O請求信息,其中包含數據地址和重疊結構的信息。

  正是這個隊列和重疊結構,設備知道要將什么數據寫到什么位置上去或從什么位置讀取數據。并通知完成結果給程序。通知方式的不同決定了它們的性能差異,同樣,每種方式都需要不同的系統設施支持。

  二、接收完成通知方式

  1、觸發設備內核對象

  • 工作機制

  線程觸發一個異步I/O請求→設備內核對象被設為未觸發狀態→線程繼續執行其他任務,直到某個點線程開始等待,設備完成I/O操作,設備內核對象被設為觸發狀態→程序收到I/O完成。

  • 硬件設施

  設備內核對象(句柄)。

  • 局限

  只能同時執行單個I/O請求。

  2、觸發事件內核對象

  • 工作機制

  線程設置事件內核對象(未觸發狀態),觸發一個異步I/O請求→線程繼續執行其他任務,直到某個點線程開始等待,設備完成I/O操作,事件內核對象被設為觸發狀態→程序收到I/O完成。

  • 硬件設施

  事件內核對象(句柄)。

  • 局限

  事件內核對象有限,不能滿足大量I/O請求。

  3、可提醒I/O

  • 工作機制

  在使用可提醒I/O時,系統為程序發起I/O的線程創建了一個APC(Async Procedure Call)隊列,在設備完成I/O操作時,驅動程序將操作結果放入該隊列,其中包含程序傳遞給系統的完成回調函數和重疊結構,對程序來說,該隊列是透明的。此時線程還不知道是否IO完成。在線程進入可提醒狀態(調用了SleepEx及Wait*等函數),系統遍歷隊列,取出完成通知,然后讓線程執行完成回調函數。

  • 硬件設施

  • 局限

  誰請求誰處理完成通知,其他線程一直閑著沒活干。

  4、I/O完成端口

  • 是什么?

  一種線程池機制(MSDN

  一種絕佳的線程間通信機制(Windows核心編程)

  一種線程同步對象

  • 做什么?

  密匙掌握在你手上!

  • 硬件設施

  I/O完成端口包含大量的主題可以討論,尤其應用在高性能易伸縮服務器上,以后再詳細討論。

3
3
 
標簽:異步IO
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()