阻塞模式下服務端要解決多個客戶連接的問題的3個思路:linux
思路1,若是連接不少(C10k)線程就會不少,消耗系統資源,並增長調度成本(Java BIO)。數組
思路2,每次都要遍歷一邊全部socket,連接不少時效率低,可能大部分連接都沒數據(select)。socket
思路3,比較理想(epoll)。函數
函數原型:性能
select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout);
select() 檢查 readfds
, writefds
中的 io描符是否可讀、可寫了,若是有ready狀態的,函數就返回。 nfds
是總共fd的個數,而不是最大的fd。線程
使用select函數步驟:指針
fd_set 是什麼?
一個結構體:rest
typedef struct fd_set { __int32_t fds_bits[__DARWIN_howmany(__DARWIN_FD_SETSIZE, __DARWIN_NFDBITS)]; } fd_set;
結構體中有一個數組,默認是是1024,這就是linux中select的函數限制最大連接數的緣由。
從新編譯內核才能提升這個數字。 FD_ISSET
就是取對應位置狀態值(0,1),而且在用戶空間,
用戶須要遍歷編一遍這個數組來檢查是哪一個socket有數據。code
select的內部實現:隊列
select的問題:
每次調用select都會有以上兩次傳遞和兩次遍歷,當連接個數多時,性能降低比較快:
select可能的改進: