本文只討論OverLapped I/O的三種異步模型及完成端口,像select、SWASelect不作討論,討論順序從劣到優,方便於循序漸進地對比,更容易區分各模型之間的差別。
1. OverLapped I/O 設備內核對象模型,這種模型雖然采用異步,但為了知道對象是否觸發,需要一直掛起線程,換個角度來說,與同步的差異不大。
2. OverLapped I/O 事件內核對象模型,這模型比較前一種就先進多了,它可以同時等待多個事件,但是waitForMultipleObject最多只能等待64個事件,也就是說如果server有6400個連接的話,就需要100個線程。我們知道線程之間上下文切換是很耗CPU的。這樣在多連接多並發的情況下還是達不到我們期望的高性能。
3. OverLapled I/O 完成例程模型,這模型較之前又有很大的改進。少了單線程最多只能處理64個事件的限制,但它在高性能方面還是存在一個問題,就是它是那個線程請求就那個線程處理,這樣會存在個別CPU核空閒著,而個別CPU核又很吃緊的情況。簡而言之,少了負載均衡。
4. 完成端口。完成端口是幾種模型中最先進的,它預先申請好線程,一般有多少個核就申請多少個線程,這樣可以避免線程間切換而浪費CPU無謂的開銷。當有請求到來,完成端口會均衡地分配到每個線程中去,從而達到CPU各核之間的負載均衡。
考慮到單文字描述還不夠直觀對比,下面再給一個簡化後對比的表:
模型
與前一種對比優點
缺點
設備內核對象模型
---
與同步的差異不大
事件內核對象模型
可以同時等待多個事件
每個線程最多只能等待64個事件,多線程下增加了CPU上下文切換的開銷
完成例程模型
少了單線程最多只能處理64個事件的限制,減少多線程上下文切換的開銷
沒有CPU的負載均衡
完成端口
使用CPU負載均衡,充分利用CPU各核