歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> WinSock 下 select() 模型的一個問題

WinSock 下 select() 模型的一個問題

日期:2017/3/1 10:37:42   编辑:Linux編程

在 Windows Socket 中, 默認 select() 一次只能支持 64個套接字. (Linux 下一個 select() 函數能夠管理的套接字多得多. 一般默認就有 4096個. select() 函數接口雖然一樣,實現上有巨大差別.) 對於一個服務器程序來說顯然太少了. 雖然可以修改FD_SETSIZE的值,但是考慮到棧大小的限制也不宜設置過大的數組長度.

自然而然的,會考慮使用多線程. 如果每個線程管理64個套接字,那麼多開幾個線程就可以突破 select()的限制.

假設這樣一個模型, 主線程只負責調用accpet(),把所有的業務邏輯都放在從線程中,以避免出現連接被拒絕的情況. 主線程accpet()了一個套接字之後,經過負載平衡算法,選中了一個線程,並把新的連接加入到該線程select()函數管理的數組中. 問題是,此時,從線程阻塞在 select() 中. 假設該從線程處理的連接全部都是死連接,並且select()函數沒有設置超時時間,那麼新加入的套接字將永遠無法得到處理.

我能想到的是: 主線程在創建業務線程時,對於每個業務線程都創建一個套接字以之關聯,稱為事件套接字, 業務現在在select()中同事檢測這個套接字的事件. 這樣,主線程accept()到新的連接後,寫某個線程的事件套接字,這樣接可以把業務線程及時喚醒.

總的來說 select() 模型在WinSock下還是有很大限制,和Linux相比64個套接字的最大限制簡直如同兒戲,對於服務器程序來說一點意義都沒有.還是應該使用 完成端口模型.

Copyright © Linux教程網 All Rights Reserved