11.1 I/O模型概覽

        在1.3 C/S模式中,server端只有一個進程,等待連接時先進行阻塞accept系統調用,新連接到來時阻塞解除,然後進程使用read、write系統調用進行數據收發,最後調用close系統調用關閉新連接的socket。這種模式在server新建連接數和併發連接很多、吞吐量都很大的情況下效率會非常低,因爲只有一個進程無法及時應對多條連接。爲了使server端能更高效地處理更多的連接,就必須使用多進程(多線程),這時需要考慮一些問題:

(1)怎樣組織這些進程(線程)使它們高效地工作?

(2)使用多進程還是多線程?

(3)進程怎樣才能更及時的收到讀寫事件?

       下面來一一探討這些問題,先考慮一下進程(線程)組織方法。

11.1.1 生產者-消費者模式

        將新連接的接受(accept)和處理(read、write、close)分開,執行接受任務產生新連接的稱爲生產者,使用新連接進行數據I/O的稱爲消費者。生產者調用accept系統調用生成新的socket,再將socket傳遞給消費者。使用這個模式就只能用多線程,不能用多進程,因爲需要在生產者和消費者之間共享數據。生產者可以是多線程,消費者也可以是多線程。這種模式的優點是可以通過動態調整生產者線程和消費者線程的數量來更好地適應新建連接和數據I/O的任務量的變化,但缺點也很大:生產者與消費者之間的數據交互需要併發保護以防止數據不一致,而併發保護就需要線程間互斥,這就會產生性能損耗(很多時候線程需要等待),也會導致代碼複雜度增大而影響穩定性(容易產生死鎖);另外,還需要實現比較複雜的算法來避免消費者“餓死”和“撐死”的現象。

11.1.2 平等模式

        使用多進程(線程),每個進程(線程)負責接受一個新連接,完成數據收發任務,關閉連接,再接受下一個新連接。多個進程(線程)可以併發執行各自的任務,它們的任務是相同的,地位是平等的,這種模式稱爲平等模式。這種模式下各個進程(線程)間的數據共享很少甚至沒有(除非相應的業務需要多個連接之間共享數據),也不需要任務分配,從而避免的生產者-消費者模式的問題。很多重要的網絡應用(如果Nginx)使用的就是平等模式。

11.1.3 多進程 vs 多線程

        生產者-消費者模式只能使用多線程,平等模式既可以使用多進程也可以使用多線程。使用多進程的優點:

(1)一個進程崩潰不會影響其它進程

(2)進程間地址空間獨立,多個進程可以同時打開更多的文件描述符

        缺點:

(1)進程的創建與銷燬的開銷較大,最好不要頻繁進行

(2)進程間數據共享不便(可以使用共享內存,但比較麻煩,而且需要併發保護;使用其它進程間通信方法可能效率低,或無法滿足需求)

        使用多線程的優點是:

(1)創建和銷燬線程的代價比較小

(2)多線程間地址空間共享,數據傳遞方便

        缺點:

(1)多線程間的數據共享可能需要併發保護,這會增加代碼複雜度,影響穩定性

(2)一個線程崩潰會導致所有線程退出,從而使服務中止

(3)一個進程能同時打開的文件描述符是有限的(理論上是65535個),使用多線程無法突破這個限制,即一個進程只能支持最多65535條併發連接

        究竟使用多進程還是多線程得看具體的應用需求。

11.1.4 輪詢 vs 阻塞喚醒

        等待事件通知有兩種方法:輪詢和阻塞喚醒。

        輪詢是指進程(線程)將socket設置爲非阻塞,然後不斷的循環進行accept系統調用或read系統調用,如果有事件則處理,否則一直循環。

        阻塞喚醒是指進程(線程)進行accept系統調用或read系統調用讀取事件,如果沒有事件則會阻塞,直到有事件被內核喚醒,處理完事件後再次阻塞等待喚醒。

        輪詢的優點是進程能夠及時處理事件,避免了睡眠-喚醒導致的狀態切換;但缺點是進程(線程)會佔用一個CPU導致其它進程無法使用這個CPU。

        阻塞喚醒的優點是有事件才響應,不會浪費CPU資源。缺點是睡眠-喚醒導致的狀態切換會有一定的開銷。不過當事件頻繁到來時進程(線程)阻塞的機會也會比較少,所以狀態切換的開銷並不大。

        綜合來看,阻塞喚醒機制通常要比輪詢更好。

11.1.5 TCP高效I/O

        以上介紹了那麼多,歸根結底是要回答一個重要的問題:TCP如何進行高效的I/O?基於以上的分析,可以得出一種比較通用的高效I/O模型:平等模式 + 多進程 + 阻塞喚醒。阻塞喚醒可以使用epoll系統調用來完成,TCP也提供了支持epoll系統調用的機制,下節我們通過分析epoll系統調用的原理來了解一下TCP高效I/O是如何完成的。

發佈了79 篇原創文章 · 獲贊 46 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章