2013-02-01 86 views
2

我讀文件abount邊緣網絡觸發epoll的功能如下:爲什麼要在邊緣觸發的epoll函數中使用非阻塞fd?

1. The file descriptor that represents the read side of a pipe (rfd) is registered on the epoll instance. 
2. A pipe writer writes 2 kB of data on the write side of the pipe. 
3. A call to epoll_wait(2) is done that will return rfd as a ready file descriptor. 
4. The pipe reader reads 1 kB of data from rfd. 
5. A call to epoll_wait(2) is done. 
....... 
....... 

epoll的使用作爲一個邊沿觸發(EPOLLET)接口建議的方法如下: 我)使用非阻塞文件描述符 II )只有在讀取(2)或寫入(2)返回EAGAIN之後才調用epoll_wait。

我明白2,但我不知道爲什麼使用非阻塞文件描述符。

任何人都可以解釋爲什麼使用非阻塞文件描述符的原因? 爲什麼在級別觸發的epoll函數中使用阻塞文件描述符是正確的?

回答

4

這個想法是當你有一個邊緣觸發的通知,有數據要完成時,試圖完全耗盡文件描述符。因此,一旦epoll()返回,您將遍歷read()write(),直到它返回-EAGAIN,此時不再有數據。

如果FD被打開阻塞,則最後read()write()也會阻止,你就不必再回到epoll()呼叫等待整個組FDS的機會。當打開非阻塞時,最後的read()/write()會返回,並且您有機會返回到輪詢。

這在電平觸發方式使用epoll()的時候,因爲在這種情況下epoll()將立即返回,如果有任何數據可拿是沒有這麼多的關注。因此,一個(僞)循環如:

while (1) { 
    epoll(); 
    do_read_write(); 
} 

會的工作,因爲你保證調用do_read_write()只要有數據。當使用邊緣觸發epoll時,如果有新的數據在do_read_write()完成和epoll()的下一個呼叫之間出現,可能會丟失新的數據。

+0

如何處理「有可能遺漏新數據的可能性」? – cong

0

我想這是因爲邊緣觸發的語義。根據語義,邊緣觸發器只會在收到EAGAIN後纔會引發另一個事件。在阻塞插座的情況下,沒有EAGAIN。你可以用其他方式定義它,但是這是Linux定義它的方式。換句話說,如果你使用阻塞套接字,你不知道什麼時候你可以安全地調用epoll_wait。

0

您必須全部讀取或寫入epoll的ET模式的所有數據,因爲et標記模式會在標記更改後觸發一次。讀完所有數據後,如果使用塊讀取或寫入,則線程必須掛起。所以必須使用非阻塞。

相關問題