IOCP全稱IOCP全稱I/O Completion Port,中文譯為I/O完成埠。IOCP是一個非同步I/O的Windows I/O模型,它可以自動處理I/O操作,併在I/O操作完成後將完成通知發送給用戶。 ...
前言
由於篇幅原因,本文假設你已經熟悉了利用Socket進行TCP/IP編程的基本原理,並且也熟練的掌握了多線程編程技術,太基本的概念我這裡就略過不提了,網上的資料應該遍地都是。
IOCP全稱IOCP全稱I/O Completion Port,中文譯為I/O完成埠。IOCP是一個非同步I/O的Windows I/O模型,它可以自動處理I/O操作,併在I/O操作完成後將完成通知發送給用戶。本文主要介紹基於IOCP的網路I/O操作(即socket的Accept、Send、Recv和Close等)。Windows提供了6種網路通信模型,分別是:
- 阻塞模型:accept、recv和send操作會阻塞線程,直到操作完成,極其低效。
- 選擇(select)模型:輪詢方式探測socket上是否有收發的操作,再調用accept、recv和send操作,核心是select()函數,比阻塞模型高效一點,缺點是一次只能探測64個socket,需要手動調用recv和send進行收發數據。
- 非同步選擇(WSAAsyncSelect)模型:利用Windows視窗消息機制響應socket操作,即當socket上有Accept、Send、Recv和Close操作發生時發送一條自定義消息給指定視窗,在視窗中響應socket操作,需要手動調用recv和send進行收發數據。與select模型相比,不需要輪詢方式探測socket,socket上有操作發生即發送通知給視窗視窗,缺點是需要一個視窗對象處理socket的消息,需要手動調用recv和send進行收發數據。
- 事件選擇(WSAEventSelect)模型:原理基本同WSAAsyncSelect模型,但是不需要視窗,利用事件(Event)機制來獲取socket上發生的I/O操作。缺點是一次只能等待64個事件,需要手動調用recv和send進行收發數據。
- 重疊 I/O(Overlapped I/O)模型:利用重疊數據結構(WSAOVERLAPPED),一次投遞一個或多個Winsock I/O請求,等這些請求完成後,應用程式會收到通知,用戶可以直接使用 I/O操作返回的數據。簡單的說:投遞一個WSASend請求和接受數據的緩衝區,系統在接收完成後在通知用戶,用戶可以直接使用收到的數據,WSASend操作同理。有兩種方式來管理重疊IO請求的完成情況(就是說接到重疊操作完成的通知):
1). 事件對象通知(event object notification)
2). 完成常式(completion routines) ,註意,這裡並不是完成埠
優點是不用管收發過程,直接提供(發送時)/使用(接收時)數據。缺點是實現略複雜。 - IOCP(I/O Completion Port)模型:本文要介紹的模型,見下文。
以上I/O模型由1-6理解難度依次提高,性能也相應地依次提高,我個人覺得重疊 I/O(Overlapped I/O)模型和IOCP(I/O Completion Port)模型並不是實現難度大,而是理解其運行機制的難度,5和6的使用比前面幾種所需代碼更少,更簡單。下麵開始正式介紹IOCP(I/O Completion Port)模型。
相關概念
1、非同步通信
我們知道外部設備I/O(比如磁碟讀寫,網路通信等)速度和CPU速度比起來是很慢的,如果我們進行外部I/O操作時線上程中等待I/O操作完成的話,此線程就會被阻塞住,相當於強迫CPU適應I/O設備的速度,這樣會造成極大的CPU資源浪費。我們沒必要線上程中等待I/O操作完成再執行後續的代碼,而是將I/O操作請求交給設備驅動去處理,我們線程可以繼續做其他事情,然後等待I/O操作完成的通知,大體的流程如下圖所示:
(未完待續……)