Linux - poll()

linux man中poll的翻譯,poll在設計上解決了select可監聽描述符的個數限制,但在一些系統中兼容性並不是很好,因此還是建議使用select來實現簡單socket應用,翻譯此文僅對epoll()的學習做一個鋪墊。

名字
poll - 等待描述符上的事件

摘要

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);  

描述
poll 的行爲與 select 相似:它等待直到描述符集準備好進行I/O操作。

被監控的描述符集由參數 fds 指定,這個參數是一個結構體數組,結構體如下:

struct pollfd {
    int   fd;         /* file descriptor */
    short events;     /* requested events */
    short revents;    /* returned events */
};

調用時需要應用 nfds 參數指定 fds 數組中元素的個數。

fd 是一個已經打開的文件的描述符。如果這個參數爲負值, 與 events 的通信將被忽略,同時 revents 將返回 0(這爲在一次poll()調用中忽略某個文件描述符提供了簡潔的辦法,即將 fd 置爲負數即可,但注意此方法不能忽略描述符0)。

events 是一個輸入域,它以位掩碼的方式來指定文件描述符fd需要監測的事件,這個變量可以被置爲0,這時可以返回的是事件只有POLLHUP/POLLERR/POLLNVAL(見下文)。

revents是一個輸出域,由內核賦值當前發生的事件。revents返回events中指定的事件之一,或者POLLHUP/POLLERR/POLLNVAL事件(這三位在events中是沒有意義的,當發生條件爲ture時則在revents中被置爲1)。

如果在任何文件描述符中都沒有事件響應,則poll()將被阻塞直到有事件發生。

timeout參數指定poll()等待直到有文件描述符爲ready狀態的超時時間,在滿足以下條件時調用將被返回:

  • 文件描述符變爲ready狀態
  • 調用被信號處理打斷
  • 等待超時

注意超時間隔以系統時鐘爲原子單位,內核調度延遲意味着阻塞間隔將較少的超出實際間隔。賦值一個負數將會導致一直阻塞。賦值爲0則將會立即返回,即使在沒有事件ready的狀態下。

<poll.h>中定義了eventsrevents中可以設置和返回的位:

  • POLLIN:可進行讀取操作
  • POLLPRI:緊急的數據ready(如:TCP的out-of-band數據)
  • POLLOUT:可進行寫入操作,然而在socket或這pipe如果寫入超過可以利用空間的數據將導致阻塞。
  • POLLRDHUP(Linux 2.6.17及以上版本):socket流的同伴closed連接,或者在寫入未完成時shut down。應用時需要保證_GUN_SOURCE宏定義被定義
  • POLLERR:條件錯誤(只在revents中被返回,在events中被忽略)
  • POLLHUP:掛起(只在revents中被返回,在events中被忽略),注意當在socketpipe等信道中讀取時,這個事件僅僅用來指示socket或pipe的夥伴在文件末尾被closed。 在未讀取的數據被讀取之後,接下來的讀取事件將返回0。
  • POLLNVAL:不合法的請求:fd未打開(只在revents中被返回,在events中被忽略)

返回值
成功時返回正數,返回值就是revent中的非零值。超時時返回0。錯誤時會返回-1,並且在errno中設置了錯誤碼。

錯誤
EBADF - 指定需要檢測的文件描述符集不合法(一個已經關閉的描述符,或者一個出現錯誤的描述符)
EINTR - 信號被捕捉,詳見 signal
EINVAL - nfds 是負數或者 timeout 中的值不合法
ENOMEM - 不能爲內部表分配內存

版本
2.1.23及以上

ppoll()

int ppoll(struct pollfd *fds, nfds_t nfds,
               const struct timespec *tmo_p, const sigset_t *sigmask);

poll()ppoll()select()pselect() 的作用相同。

發佈了37 篇原創文章 · 獲贊 24 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章