2017-10-10 58 views
-1

我正在運行linux 4.13.3,gcc 7.2.0。當在非阻塞服務器套接字上接收到新請求時,爲什麼從睡眠()恢復進程?

相關的代碼是......。這樣

while(1) { 
    // let server be the nonblocking server socket 
    int client = accept(server, &addr, &addrlen); 
    if(client != -1) { 
     foo(client); 
    } else { 
     sleep(someTime); 
    } 
} 

我知道我應該使用select /調查/ epoll的,爲此目的,

但爲什麼犯規睡眠()返回時,在套接字上接收新的數據?

+2

這樣做是因爲'sleep'不只是把過程睡覺。沒有檢查文件描述符上的事件(除非它引起信號)。您可能想要使用['select'](http://man7.org/linux/man-pages/man2/select.2.html)或['poll'](http://man7.org/linux/ man-pages/man2/poll.2.html)。 –

+0

所以真正的問題應該是,當一個相關的套接字接收到數據時,爲什麼沒有任何信號發生,對吧? –

+0

當我說「信號」時,我的意思是'SIGINT'或'SIGUSR1'或類似的。這些信號通常不是由描述符產生的。如果你想接收關於套接字(或者一般描述符)的通知,那麼首先學習'select'或者'poll'(如我之前的評論中提到的)。這些都是常見的方式,既要去睡覺*和*輪詢描述符事件。還有其他方法來輪詢描述符,但從這兩個開始。 –

回答

-1

void sig_handler(int sig){} 
... 
signal(SIGIO, sig_handler); 
fcntl(server, SETOWN, getpid()) 
fcntl(server, SETFL, fcntl(server, GETFL) | O_NONBLOCKING | O_ASYNC); 
...