2012-12-24 78 views
0

我有兩個文件描述符,一個讀取管道上的文件描述符和另一個套接字連接描述符。它們都不是非阻塞的。它們都被添加到單個EPOLLIN事件的epoll上下文中。最後,我用timeout = -1調用epoll_wait。以下是示例代碼。我有 兩個問題: -epoll返回0事件

  1. 不要管和連接描述符需要非阻塞。這不是邊緣觸發的。如果是,是好的做法還是強制性的,如果是強制性的,爲什麼?

  2. 我將超時設置爲-1,但epoll_wait立即返回值爲0.爲什麼會發生這種情況?當超時時間爲-1時,只有在發生事件時才返回epoll_wait。

    int total_fd_ready = -1; 
    struct epoll_event pipe_event, connection_event, total_events[64]; 
    
    pipe_event.data.fd = pipe_fd[0]; 
    piple_event.events = EPOLLIN; 
    connection_event.data.fd = conn_fd; 
    connection_event.events = EPOLLIN; 
    
    total_fd_ready = Epoll_wait(epoll_fd, total_events, 64, -1); 
    printf("%d\n", total_fd_ready); 
    

    Epoll_wait被定義爲

    int Epoll_wait(int e_fd, struct epoll_event *events, int max_events, int timeout) 
    { 
    #ifdef DBG 
         printf("Epoll_wait called on epoll_fd: %d with max_events: %d and timeout: %d\n", e_fd, max_events, timeout); 
    #endif 
    
    int result = -1; 
    if(result = (epoll_wait(e_fd, events, max_events, timeout)) < 0) 
         if(errno != EINTR) 
           err_sys("epoll_wait error with epoll fd: %d and timeout : %d\n", e_fd, timeout); 
         #ifdef DBG 
         else 
           printf("epoll_wait was interrupted\n"); 
         #endif 
    return result; 
    } 
    

UPDATE: 發現的問題,雖然我無法解釋爲什麼結果被設置爲0。我需要護腕下面的if語句

if((result = (epoll_wait(e_fd, events, max_events, timeout))) < 0) 
+0

如何聲明和初始化total_events? –

+0

更新了它的代碼 – Jimm

+0

如果編譯時啓用了警告,例如用'gcc -Wall',編譯器會適當的提醒你 –

回答

4

答案是比較運算符<的優先級高於分配,這意味着result被賦予表達式(epoll_wait(e_fd, events, max_events, timeout)) < 0的結果。

+0

啊,這很有道理,謝謝!你知道我是否需要讓我的文件描述符不阻止epoll工作?我不明白爲什麼對於邊緣觸發的場景,文件描述符應該是非阻塞的 – Jimm

+0

因爲你不知道你的下一個調用'read(2)'是否會阻塞,完全破壞了'epoll(7)的複用性質, '。 –

+0

如果epoll返回帶EPOLLIN事件的套接字描述符,爲什麼會調用讀取塊?通常情況下,我註冊套接字fd讀事件,然後當epoll_wait返回,我檢查如果套接字fd是「事件」的一部分,如果是,那麼它不應該阻止。即使有0超時,也會檢查返回的「事件」是否包含要讀取的套接字。 – Jimm