在閱讀UNIX環境高級編程中,發現只寫了select和poll,關於epoll的回調機制還有所不理解。html
首先要理解LINUX網絡IO多路複用,IO多路複用在Linux下包括了三種,select, poll, epoll,抽象來看,他們功能是相似的,但具體細節各有不一樣:首先都會對一組文件描述符進行相關事件的註冊,而後阻塞等待某些事件的發生或等待超時。更多細節詳見下面的 "具體怎麼用"。IO多路複用均可以關注多個文件描述符,但對於這三種機制而言,不一樣數量級文件描述符對性能的影響是不一樣的,下面會詳細介紹。linux
select將監聽的文件描述符分爲三組,每一組監聽不一樣的須要進行的IO操做。readfds是須要進行讀操做的文件描述符,writefds是須要進行寫操做的文件描述符,exceptfds是須要進行異常事件處理的文件描述符。這三個參數能夠用NULL來表示對應的事件不須要監聽。編程
當select返回時,每組文件描述符會被select過濾,只留下能夠進行對應IO操做的文件描述符。數組
所以能夠看出,一旦文件描述符的數值超出1024,計算出的下標就有可能超出__int32_t數組的最大下標位置,因此有可能會出現數組越界的問題。服務器
和select用三組文件描述符不一樣的是,poll只有一個pollfd數組,數組中的每一個元素都表示一個須要監聽IO操做事件的文件描述符。events參數是咱們須要關心的事件,revents是全部內核監測到的事件。網絡
epoll_create用於建立一個epoll實例,而epoll_ctl用於往epoll實例中增刪改要監測的文件描述符,epoll_wait則用於阻塞的等待能夠執行IO操做的文件描述符直到超時。性能
關於上述的回調機制如何實現,還在查閱epoll相關源碼中線程
狀態持續通知和狀態變化通知。unix
這兩個概念來自電路,triggered表明電路激活,也就是有事件通知給程序,level-triggered表示只要有IO操做能夠進行好比某個文件描述符有數據可讀,每次調用epoll_wait都會返回以通知程序能夠進行IO操做,edge-triggered表示只有在文件描述符狀態發生變化時,調用epoll_wait纔會返回,若是第一次沒有所有讀完該文件描述符的數據並且沒有新數據寫入,再次調用epoll_wait都不會有通知給到程序,由於文件描述符的狀態沒有變化。htm
select和poll都是狀態持續通知的機制,且不可改變,只要文件描述符中有IO操做能夠進行,那麼select和poll都會返回以通知程序。而epoll兩種通知機制可選。
poll和select基本上是同樣的,poll相比select好在以下幾點:
select比poll好在下面幾點
但整體而言 select和poll基本一致。
epoll優於select&poll在下面幾點:
https://zhuanlan.zhihu.com/p/...
https://www.jianshu.com/p/019...
https://www.cnblogs.com/Anker...
https://www.cnblogs.com/anker...