I/O复用函数的比较
select poll 和 epoll 三組I/O復(fù)用系統(tǒng)調(diào)用都能夠同時(shí)監(jiān)聽多個(gè)文件描述符。它們將等到由timeout參數(shù)指定的超時(shí)時(shí)間,直到一個(gè)或者多個(gè)文件描述符上有時(shí)間發(fā)生時(shí)返回,返回值就是就緒的文件描述符的數(shù)量。返回0表示沒有事件發(fā)生。現(xiàn)在我們從事件集 最大支持文件描述符數(shù)和具體實(shí)現(xiàn)等四個(gè)方面進(jìn)一步比較它們的異同,以明確在實(shí)際應(yīng)用中應(yīng)該選擇哪個(gè)。
這三組函數(shù)都是通過某種結(jié)構(gòu)體變量來告訴內(nèi)核監(jiān)聽那些文件描述符上的那些事件,并使用該結(jié)構(gòu)體類型的參數(shù)來獲取內(nèi)核處理的結(jié)果。
select的參數(shù)類型是fd_set沒有將文件描述符和事件進(jìn)行綁定,它僅僅是一個(gè)文件描述符的集合,因此select需要提供三個(gè)這種類型的參數(shù)來分別傳入和輸出可讀 可寫及異常等事件。這一方面使得select不能處理更多類型的事件,另一方面由于內(nèi)核對(duì)fd_set集合的在線修改,應(yīng)用程序下次調(diào)用select前不得不重置這三個(gè)fd_set集合。
poll的參數(shù)類型pollfd則多少聰明一些。他把文件描述符和事件都定義其中,任何事件都統(tǒng)一處理,從而使得編程接口簡潔得多。并且內(nèi)核每次修改的是pollfd結(jié)構(gòu)體的revent成員,而events成員保持不變,因此下次調(diào)用poll時(shí)應(yīng)用程序無需重置pollfd類型的事件集參數(shù)。
由于每次select 和poll調(diào)用都返回整個(gè)用戶注冊的事件集合,所以應(yīng)用程序索引就緒文件描述符的事件復(fù)雜度為N。epoll則采用與select和poll完全不同的方式來管理用戶注冊的事件。它在內(nèi)核中維護(hù)一個(gè)事件表,并提供一個(gè)獨(dú)立的系統(tǒng)調(diào)用epoll_ctl來控制往其中添加 刪除 修改事件。這樣每次epoll_wait調(diào)用都直接從該內(nèi)核事件表中取得用戶注冊的事件,而無須反復(fù)從用戶空間讀取這些事件。epoll_wait系統(tǒng)調(diào)用的events參數(shù)僅用戶返回就緒的事件,這使得應(yīng)用程序索引就緒文件描述符的時(shí)間復(fù)雜度為1。
總結(jié)
以上是生活随笔為你收集整理的I/O复用函数的比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP -----上传文件
- 下一篇: 移除HTML5 input在type=n