「重磅」linux epoll 讓你更好使用epoll「深入靈魂問題」

「重磅」linux epoll 讓你更好使用epoll「深入靈魂問題」

1. epoll中管理註冊文件描述符列表的key是什麼格式?

key是通過文件描述符(比如1,2,3)以及打開的文件句柄(open file handle)組合成的。

️2. 如果將同一個文件描述符重複add(註冊)到epoll 會發生什麼?

調用epoll_ctl 會得到EEXIST錯誤碼。但是如果你添加的是通過dup、dup2、fcntl(F_DUPFD)複製得到的文件描述符,這個是允許的。一般後面這種操作是用於過濾不同的事件。

️3. 如果將文件描述符添註冊兩個不同的epoll 實例,在該句柄上觸發的事件是否都會上報給這兩個epoll 實例?

答案是肯定的,但是需要區別(通過fork 繼承的epoll實例,fork繼承的epoll實例系統只會喚醒啟動一個)

️4. 關閉一個文件描述符,會自動從所有epoll實例的註冊列表中刪除嗎?

會的,但是必須與該描述符相關聯的都需要關閉才可以(包括dup、dup2、fcntl、fork複製的描述符)

️5. 是否可以將epoll的文件描述符註冊到自身的epoll實例中?

epll_ctl 將會返回錯誤(EINVAL),但是你可以將該epoll 描述符添加到另外一個epoll實例

️6. epoll文件描述符是否支持poll、epoll、select?

可以的,如果該描述符有需要處理的事件,那麼將會觸發可讀事件(readable)

️7. 能否通過UNIX domain socket將epoll實例的文件描述符(注意是實例本身不是註冊的文件句柄)發送給另外一個進程?

可以的,但是這樣做沒有任何意義,因為接受進程沒有對應的註冊文件列表。

️8.如果在調用epoll_wait時有多個事件觸發,它們是分開返回還是一起返回?

一起返回

️9.在邊緣模式(EPOLLET)模式下,是否有必要一直read/write直到errno=EAGAIN?

當你同epoll_wait收到事件時,表示這些文件描述符上的I/O請求已經準備好了,你必須要read/write直到EAGAIN。

對於一些packet/toke-oriented的文件描述符(eg:datagram socket,terminal in canonical mode),這也是惟一能夠判斷是否把I/O空間內容讀完(寫完)的方式。

對於一些流式的文件描述符(eg:pipe、FIFO、stream sock)建議也是通過這種方式,如果通過read(2)返回的讀到的字節與給定的buffer大小比較來判斷是否已經讀完(ret_byte < buffer_size),很有可能會讀取不到後面的FIN包

️10.對文件描述符的操作是否會對一些已經到達但是還未觸發的事件(epoll_wait)產生影響?

對文件描述符的flag做remove操作,將不會產生什麼影響。但是如果對其做EPOLL_CTL_MOD將會重新獲取到有效的I/O事件(epoll_wait).比如:ET模式第一次沒有將緩衝區數據讀完,正常情況下餘下部分的數據將不會及時讀取到,但是如果此時你對文件描述符做一個MOD操作那麼epoll_wait又將返回該可讀事件。


分享到:


相關文章: