通常使用 poll 檢測 socket 或標準輸入時,只要指定 POLLIN 標誌位,就能夠檢測是否有數據到達,或者鏈接斷開:git
1 struct pollfd fds[3]; 2 fds[0].fd = STDIN_FILENO; 3 fds[0].events = POLLIN; 4 fds[1].fd = sock_fd; 5 fds[1].events = POLLIN; 6 fds[2].fd = pipe_fd; 7 fds[2].events = POLLIN; 8 ret = poll(fds, 3, -1); 9 if (ret > 0) { 10 if (fds[0].revents & POLLIN) { 11 // handle stdin 12 ... 13 } 14 if (fds[1].revents & POLLIN) { 15 // handle socket input 16 ... 17 } 18 if (fds[2].revents & POLLIN) { 19 // handle pipe input 20 ... 21 } 22 }
當 read 結果返回 0 時表示相應鏈接斷開。github
而對於 pipe,只檢測POLLIN是感知不到管道斷開的,當管道斷開時,會在revents設置POLLHUP,必需額外檢測此標誌位:數組
1 if (pfd[2].revents & POLLHUP) { 2 // handle pipe break 3 ... 4 }
而當 poll 一個已經關閉的句柄時(句柄號 >=0 有效),poll 自己並不返回錯誤,而是給對應的句柄事件中設置 POLLNVAL 標誌位:socket
1 if (pfd[2].revents & POLLNVAL) { 2 // handle pipe close 3 ... 4 }
若 poll 一個無效句柄時(句柄號爲-1),poll 自己仍不返回錯誤,但該句柄必定沒有任何事件可供檢測與返回。所以可用於佔位處理,測試
例如固定從數組某個下標中取出某個句柄時能夠在不相關位置設置-1句柄,這樣就不用再去判斷當前有事件的句柄的源句柄是哪個了:spa
1 struct pollfd fds[3]; 2 fds[0].fd = STDIN_FILENO; 3 fds[0].events = POLLIN; 4 fds[1].fd = -1; 5 fds[1].events = POLLIN; 6 fds[2].fd = pipe_fd; 7 fds[2].events = POLLIN; 8 ret = poll(fds, 3, -1); 9 ……
例如當沒有 socket 句柄時,該位置保持-1,這樣能夠不用將管道句柄上移,從而能夠固定從fds[2]中取出管道句柄。code
固然若是傳入 poll 的句柄數組中全部句柄都爲無效句柄時,poll仍不返回錯誤,此時若提供超時,可當成sleep使用;blog
若不提供超時,則會進入無限期等待……事件
測試代碼 ip