Remove ads
来自维基百科,自由的百科全书
輸入輸出完成端口(Input/Output Completion Port,IOCP), 是支持多個同時發生的異步I/O操作的應用程式編程接口,在Windows NT的3.5版本以後[1],或AIX 5版以後[2]或Solaris第十版以後,開始支持。
此條目需要擴充。 (2014年4月11日) |
此條目需要精通或熟悉相關主題的編者參與及協助編輯。 (2014年4月11日) |
IOCP特別適合C/S模式網絡伺服器端模型。因為,讓每一個socket有一個線程負責同步(阻塞)數據處理,one-thread-per-client的缺點是:一是如果連入的客戶多了,就需要同樣多的線程;二是不同的socket的數據處理都要線程切換的代價。
通常的辦法是,線程池中的工作線程的數量與CPU內核數量相同,以此來最小化線程切換代價。一個IOCP對象,在作業系統中可關聯着多個Socket和(或)文件控制端。 IOCP對象內部有一個先進先出(FIFO)隊列,用於存放IOCP所關聯的輸入輸出端的服務請求完成消息。請求輸入輸出服務的進程不接收IO服務完成通知,而是檢查IOCP的消息隊列以確定IO請求的狀態。 (線程池中的)多個線程負責從IOCP消息隊列中取走完成通知並執行數據處理;如果隊列中沒有消息,那麼線程阻塞掛起在該隊列。這些線程從而實現了負載均衡。
IOCP是唯一一個不需要安全屬性的Windows內核對象。 這是因為IO完成端口在設計時就是只在一個進程中使用。
使用CreateIoCompletionPort函數創建一個新的IOCP,或把socket或文件句柄與一個已存在的IOCP關聯起來。
一個線程,第一次調用GetQueuedCompletionStatus函數時,該線程就成為關聯了該IOCP的線程,直到下述三種情形之一發生:
即,一個線程在任何時刻最多關聯一個IOCP。
線程調用GetQueuedCompletionStatus函數等待放入IOCP的I/O完成包(completion packet)。IOCP擁有一個線程池。阻塞在IOCP上的線程按照後進先出(LIFO)順序被釋放(這是為了減少線程切換的代價);而一個線程的完成包按照先進先出(FIFO)順序從IOCP的隊列中取走。IOCP有一個最大允許並發的線程數量上限,在CreateIoCompletionPort函數中指定,每次I/O完成包在從隊列取走前檢查關聯於該IOCP且正在並發執行的線程數量是否達到該限。因其他原因(如調用SuspendThread函數)而掛起的線程不算作正在執行的線程。CompletionKey(完成鍵)一般作為「單句柄數據」的結構體(PER_HANDLE_DATA),用來標識是哪個設備的I/O完成操作已經完成。IO重疊結構(Overlapped)一般作為「單IO數據」的結構體(PER_IO_DATA),該結構體的第1個成員為OVERLAPPED結構體,用來標識是設備的具體哪個操作。
線程可以用PostQueuedCompletionStatus函數在IOCP上投寄一個完成包。
關閉IOCP之前,必須先關閉關聯在該IOCP之上的所有File Handle或socket。
Jeffrey Richter說:「完成端口可能是最為複雜的內核對象」。[3] Windows中利用CreateIoCompletionPort命令創建完成端口對象時, 作業系統內部為該對象自動創建了5個數據結構,分別是:
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.