用libevent進行網絡編程(fork,thread,event_based)

用libevent進行網絡編程(fork,thread,event_based)

 

1、我們知道處理多用戶時有幾種方法:

(1)、fork():一個新的connection()進來,用fork()產生一個process處理。

(2)、pthread_create()產生一個新的thread處理。

(3)、把新的connection丟入Event-based Array,然後由Main Process以Nonblocking方式處理所有IO。

 

2、這三種方法當然也有自個的缺點:

  (1)、用fork()問題在於一個Connection進來的成本太高。(子進程要獲得父進程的的數據控件,堆,棧。父子進程之間並不共享這些存儲空間)。

(2)、用多線程的問題在於Thread-safe與Deadlock問題難以解決,另外由Memory-leak問題要處理。

(3)、用Event-based的方式在於實現上不好寫,尤其是要注意到事件產生是必須要Nonblocking,於是會需要作Buffering的問題。多線程所會遇到的Memory-leak問題在這兒會更嚴重。而再多CPU的系統上沒有辦法使用到所有的CPU資源。

 

3、當然,針對前面兩項由自個的解決方法:

  (1)以poll的方式解決:當一個process處理完一個Connection後,不直接死掉,而是繼續回到accept()的狀態繼續處理,但這樣會遇到Memory-leak的問題,於是採用這種方式的人通常會加上“處理過N個Connection後死掉,由Parent process再fork()新的。”最有名的例子是Apache1.3。

(2)Thread-safe的問題可以透過自己撰寫,或是尋找其他的Thread-safe庫直接使用。Memory-leak的問題可以試着透過Garbage Connection Libray分析出來。Apache2.0的Thread MPM就是使用這個模式的。

 

4、然而,目前高效的server都偏好採用event-based,一方面是沒有Create Process/Thread所造成的開銷,令一方面是不需要透過Memory或是Mutex在不同的Process/Thread之間交換。而event-based在實際上的幾個複雜的地方在於:

  select()與poll()的效率過慢,造成每次都要判斷“由那些event發生”,這件事的成本很高,這個BSD上的改進爲kqueue()、linux上的改進爲epoll(),這兩個函數都不是標準,於是不同的平臺上需要做修改。因爲Nonblocking,所以再write()或者send()時不能一次完成,這就需要自己Buffering。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章