select的缺點(diǎn):
1、單個(gè)進(jìn)程能夠監(jiān)視的文件描述符的數(shù)量存在最大限制,通常是1024,當(dāng)然可以更改數(shù)量,但由于select采用輪詢的方式掃描文件描述符,文件描述符數(shù)量越多,性能越差;(在linux內(nèi)核頭文件中,有這樣的定義:#define __FD_SETSIZE? ? 1024)
2、內(nèi)核 / 用戶空間內(nèi)存拷貝問(wèn)題,select每次都會(huì)改變內(nèi)核中的句柄數(shù)據(jù)結(jié)構(gòu)集,因而每次select調(diào)用時(shí)都需要從用戶空間向內(nèi)核空間復(fù)制所有的句柄數(shù)據(jù)結(jié)構(gòu),產(chǎn)生巨大的開銷
3、select返回的是含有整個(gè)句柄的數(shù)組,應(yīng)用程序需要遍歷整個(gè)數(shù)組才能發(fā)現(xiàn)哪些句柄發(fā)生了事件
4、select的觸發(fā)方式是水平觸發(fā),應(yīng)用程序如果沒(méi)有完成對(duì)一個(gè)已經(jīng)就緒的文件描述符進(jìn)行IO操作,那么之后每次select調(diào)用還是會(huì)將這些文件描述符通知進(jìn)程
epoll實(shí)現(xiàn):
epoll在內(nèi)核中會(huì)維護(hù)一個(gè)紅黑樹和一個(gè)雙向鏈表,紅黑樹存放通過(guò)epoll_ctl方法向epoll對(duì)象中添加進(jìn)來(lái)的事件,所以不需要每次調(diào)用epoll_wait都全量復(fù)制所有的事件結(jié)構(gòu)。雙向鏈表存放就緒的事件,所有添加到epoll中的事件都會(huì)與設(shè)備(網(wǎng)卡)驅(qū)動(dòng)程序建立回調(diào)關(guān)系,也就是說(shuō),當(dāng)相應(yīng)的事件發(fā)生時(shí)會(huì)調(diào)用這個(gè)回調(diào)方法,這個(gè)回調(diào)方法在內(nèi)核中叫ep_poll_callback,它會(huì)將發(fā)生的事件添加到rdlist雙鏈表中。調(diào)用epoll_wait就會(huì)直接返回鏈表中的就緒事件,效率高。
select適合少量活躍連接,一般幾千。
epoll適合大量不太活躍的連接。
如果有大量活躍連接可以使用多進(jìn)程+select。