select、poll、epoll

兼容性

select() 和 poll() 相對于 信號驅(qū)動和epoll() 在不同os之間的可移植性更高, 但是當fd過多的時候, 效率也遠低于后兩者.

觸發(fā)方式

  • poll 和 select 只支持 水平觸發(fā)
  • 信號驅(qū)動只支持邊緣觸發(fā)
  • epoll支持水平觸發(fā)和邊緣觸發(fā)

select

  • select返回的是含有整個句柄的數(shù)組,select 返回后, 程序并不知道是哪些 fd 準備就緒, 而只知道一共有多少個就緒了, 需要進程自己對傳遞過去的集合進行遍歷和判斷
  • select的觸發(fā)方式是水平觸發(fā),應用程序如果沒有完成對一個已經(jīng)就緒的文件描述符進行IO操作,那么之后每次select調(diào)用還是會將這些文件描述符通知進程
  • 內(nèi)核 / 用戶空間內(nèi)存拷貝問題,select每次都會改變內(nèi)核中的句柄數(shù)據(jù)結構集,因而每次select調(diào)用時都需要從用戶空間向內(nèi)核空間復制所有的句柄數(shù)據(jù)結構,產(chǎn)生巨大的開銷
  • 單個進程能夠監(jiān)視的文件描述符的數(shù)量存在最大限制,通常是1024,當然可以更改數(shù)量

poll

  • 每個fd都有屬于自身的 pollfd 結構, 它將 感興趣事件和觸發(fā)的事件分成了 events 和 revents. events 的值告訴內(nèi)核我們關心的是描述符的哪些事件 ; 當某個 fd 有事件觸發(fā)了之后, 就由內(nèi)核修改 revents 的數(shù)據(jù), 互不干擾, 所以不必像 select 那樣, 每次調(diào)用都必須重置 fd 集合.
  • 數(shù)組大小沒有限制
  • 跟 select() 一樣, poll返回后, 程序并不知道是哪些 fd 準備就緒, 而只知道一共有多少個就緒了, 需要進程自己對傳遞過去的集合進行遍歷和判斷

信號驅(qū)動

  • 不需要由用戶進程復制fd數(shù)組到內(nèi)核
  • 信號處理不好可能會導致進程出問題.

epoll

  • epoll 支持水平觸發(fā)和邊緣觸發(fā). epoll 的機制類似于信號驅(qū)動, 都是進程告訴內(nèi)核對哪些 fd 感興趣, 然后對應的fd上有事件的時候, 由內(nèi)核主動通知進程, 進程再進行相應的處理.
  • 可以避免復雜的信號處理流程(比如信號隊列溢出時的處理)
  • 靈活性高, 可以指定我們希望檢查的事件類型(例如檢查 socket 的讀就緒事件、寫就緒事件、或者兩者都檢查)

總結

  • select適合少量活躍連接,一般幾千。兼容平臺多。

  • epoll適合大量不太活躍的連接。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容