完成埠(上) (轉)
完成埠
完成埠是到目前為止最為複雜的輸入輸出模式。然而,當一個應用不得不同時處理大量的socket時,它也提供了使達到最佳的可能性。不幸的是,完成埠只能用在 NT和上。由於完成埠被設計得極為複雜,它應該成為員的青年禁衛軍,只有在被迫面對幾百甚至幾千個併發的socket、你又希望在新增後可以獲得更好的scale時,才被派上戰場。關於完成埠,最重要的是記住這一點:如果你為winnt/2000開發處理大量socket I/O 請求的高效能服務,它是你的最佳選擇(比如,服務)。
本質上完成埠模式要求你建立一個完成埠來管理重疊i/o請求,用一定數量的執行緒來處理已完成的重疊i/o請求.注意,事實上完成埠是win32,winnt,的內建的,它能操作的不僅僅是socket控制程式碼。但是,本章將把討論範圍侷限於在socket控制程式碼上下文中,如何利用完成埠的優勢。
在開始使用完成埠模式之前,我們必須建立一個完成埠物件,用它來管理任意數量的socket控制程式碼上的多I/O請求。完成這一動作需要CreateIoCompletionPort,它具有如下形式的定義:
HANDLE CreateIoCompletionPort(
HANDLE FileHandle,
HANDLE ExistingCompletionPort,
D CompletionKey,
DWORD NumberOfConcurrentThreads
);
在瞭解引數的細節之前,要明白這個函式事實上有兩個目的:
。建立一個完成埠物件
。把一個控制程式碼關聯到完成對口上。
開始建立完成埠時,我們唯一感興趣的引數是NumberOfConcurrentThreads,前面的三個引數可以忽略不計。引數NumberOfConcurrentThreads用來指定在一個完成埠上可以併發的執行緒數量。理想的情況是,一個上只執行一個執行緒,這樣可以避免執行緒上下文切換的開銷。如果這個引數的值為0,那就是告訴系統執行緒數與處理器數相同。我們可以用下面的程式碼來建立I/O完成埠。
CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
NULL, 0, 0);
這段程式碼返回一個控制程式碼,在關聯socket控制程式碼時,它用來標識這裡的完成埠。
工作者執行緒和完成埠
成功的建立了完成埠物件,就可以把socket控制程式碼(注意,原文用的是handles,複數)關聯上去。可是在做這一步之前,還有一件必須完成的工作:建立一個或多個工作者執行緒,當socketI/O 請求被投遞到完成埠物件時,這些執行緒為完成埠服務。說到這裡,你可能想知道應該建立多少個執行緒來為完成埠服務。事實上這是完成埠模式更為複雜的一面,因為這需要你通盤考慮整個應用的設計,才能決定用多少個執行緒來為I/O請求服務。注意到這一點是很重要的:在呼叫CreateIoCompletionPort時指定的併發執行緒的個數,和建立的工作者執行緒的個數是有區別的,
或者說,它們不是一回事。我們在前面推薦的做法,是呼叫CreateIoCompletionPort時指定每個處理器上只有一個執行緒,以避免執行緒上下文切換的開銷。CreateIoCompletionPort的引數NumberOfConcurrentThreads明確的告訴系統,每次只允許n個執行緒可以操作完成埠。如果你為一個完成埠建立的工作者執行緒比n多,那一次只能有n個執行緒可以進行操作(確切地說,在一小段時間內,系統啟用的執行緒有可能超過n,但系統會很快將這個數量減小到n)。你可能會覺得奇怪:我明明已經在CreateIoCompletionPort中指定了一個值,幹嗎要建立比它多的工作者執行緒。
正如我前面提到的,這取決於你的整個應用的設計。如果一個工作者執行緒呼叫sleep、WaitForSingle之類的函式,然後,它掛了,另一個執行緒就可以取代它的位置。或者說,你總是希望有足夠多可以的執行緒,來滿足你在CreateIoCompletionPort指定的那一個數字。這樣,如果你預見到工作者執行緒可能阻塞,你就找到了一個理由,來建立比CreateIoCompletionPort的引數NumberOfConcurrentThreads多的工作者執行緒。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-998545/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- IOCP 完成埠
- 防火牆埠(上)(轉載)防火牆
- CreateIoCompletionPort和完成埠
- 在 Fedora 上使用 SSH 埠轉發
- Windows 上使用 PowerShell 設定防火牆規則和埠轉發; Windows 上配置埠轉發,將 3389 埠的流量重定向到自定義埠;Windows防火牆
- 如何用nginx在本地把9000埠轉發到80埠上Nginx
- Windows上Oracle開放防火牆埠問題(轉)WindowsOracle防火牆
- 檢查特定埠上正在執行的程式名(轉)
- 在Linux上配置Resin 80埠自啟動(轉)Linux
- 埠大全(轉)
- 交換機埠滿了 怎麼樣才能共享上網(轉)
- 實現埠對埠的聊天 (轉)
- 用完成埠開發大響應規模的Winsock應用程式(3) (轉)
- 用完成埠開發大響應規模的Winsock應用程式(2) (轉)
- 玩轉SSH埠轉發
- 埠轉發方法
- SSH 埠轉發
- SSH埠轉發
- 常用埠列表(轉)
- 快速清空埠上的配置
- Linux下PCI轉串列埠卡及USB轉串列埠Linux串列埠
- 用完成埠開發大響應規模的Winsock應用程式(5/完) (轉)
- .NET非同步程式設計:IO完成埠與BeginRead非同步程式設計
- 關於埠轉發
- linux埠列表 (轉)Linux
- 串列埠通訊 (轉)串列埠
- 埠碰撞技術讓開放埠更安全(轉)
- ssh埠轉發(ssh隧道)
- iptables 配置埠及轉發
- Linux IPTABLES埠轉發Linux
- 防火牆埠(下)(轉載)防火牆
- 防火牆埠(中)(轉載)防火牆
- Win10 埠轉發Win10
- IBM串列埠線序以及串列埠線的做法(轉)IBM串列埠
- js+nodejs完成檔案上傳NodeJS
- linux上檢視埠使用的命令Linux
- ADB 連不上---埠被佔用
- Linux-Windows 埠轉發LinuxWindows