推 iversonjimmy:非常謝謝您的解說,對我很有幫助~ 10/02 00:21
※ 引述《iversonjimmy (Effort)》之銘言:
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: Linux
: 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
: 問題(Question):
: 請問各位,fork和select都是可以做到server服務multi-client的socket程式,
: 那這兩種方法的優缺點呢?
: 似乎很多人都推select,但我不太懂fork的缺點在哪?
: 當accept新的socket_fd時,就fork new child process,
: 處理結束後就kill掉該child process,
: 感覺兩者若要比較的話?該從哪個方向去比較優缺點呢?
: 餵入的資料(Input):
: 預期的正確結果(Expected Output):
: 錯誤結果(Wrong Output):
: 程式碼(Code):(請善用置底文網頁, 記得排版)
: 補充說明(Supplement):
從伺服器的角度來看,如果讓每個連線占用單獨的行程 (process)
由於建立行程的成本較高,能夠同時服務的連線數量就會十分受限。
但是,這跟用不用 select 是兩件事情。
select 允許你監看多個 sockets,當任何 socket 的狀態
變成可讀/寫時,select 會"通知"你可以對 socket 進行操作
這裡使用通知其實是比較抽象的說法,簡單的 socket read 例子如下
fd_set socks;
struct timval timeout = {1,0};
// ... init
while(1){
any_readable = select(FD_SETSIZE, &socks, NULL, NULL, &timeout);
// 上一行會 block 直到有任一 socket 變為可讀或者 timeout 發生
// 以下進行檢查並從可讀的 socket 讀取資料,處理完後繼續 select
}
上面的例子修改一下就可以讓一個行程負責 select 而另一個行程負責
資料處理,就需要使用 fork。
select() 是個通用但效能並不最佳的 I/O demultiplexing 方案
因此版友提到的 poll 是另一個方案;另外還有 /dev/poll, epoll, kqueue, IOCP
等,都可以搭配單一行程或多行程(執行緒)來使用,時下也有許多跨平台的程式庫
例如 libevent 或 boost::asio 等直接幫你包裝不同的方案,提供一致的介面。
你只要根據專案需求去選擇想要的架構,至於有那些架構,可以參考 C10K 這篇老文章
雖然他已經沒甚麼在維護,但還是非常值得一讀。(http://www.kegel.com/c10k.html )
或者你可以直接去玩 ZeroMQ ,不需要支援特定應用層協定的話,他倒是很方便。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.170.79.48