# include < sys/ poll. h>
int poll ( struct pollfd * fds, unsigned int nfds, int timeout) ;
和select()不同,poll()沒有使用低效 的三個基於位的文件描述符set,而是採用了一個單獨的結構體pollfd數組,由fds指針指向這個組 。pollfd結構體定義以下:
數組
# include < sys/ poll. h> struct pollfd { int fd; /* file descriptor */ short events; /* requested events to watch */ short revents; /* returned events witnessed */ } ; |
每個pollfd結構體指定了一個被監視的文件描述符,能夠傳遞多個結構體,指示poll()監視多個文件描述符。每一個結構體的 events域是監視該文件描述符的事件掩碼,由用戶來設置這個域。revents域是文件描述符的操做結果事件掩碼。內核在調用返回時設置這個域。 events域中請求的任何事件均可能在revents域中返回。合法的事件以下:
POLLIN
有數據可讀。
POLLRDNORM
有 普通數據可讀。
POLLRDBAND
有優先數據可讀。
POLLPRI
有緊迫數據可讀。
POLLOUT
寫 數據不會致使阻塞。
POLLWRNORM
寫普通數據不會致使阻塞。
POLLWRBAND
寫優先數據不會致使阻塞。
POLLMSG
SIGPOLL 消息可用。
此外,revents域中還可能返回下列事件:
POLLER
指定的文件描述符發生錯誤。
POLLHUP
指 定的文件描述符掛起事件。
POLLNVAL
指定的文件描述符非法。
這些事件在events域中無心義,由於它們在合適的 時候老是會從revents中返回。使用poll()和select()不同,你不須要顯式地請求異常狀況報告。
POLLIN | POLLPRI等價於select()的讀事件,POLLOUT | POLLWRBAND等價於select()的寫事件。POLLIN等價於POLLRDNORM | POLLRDBAND,而POLLOUT則等價於POLLWRNORM。
例如,要同時監視一個文件描述符是否可讀和可寫,咱們能夠設置 events爲POLLIN | POLLOUT。在poll返回時,咱們能夠檢查revents中的標誌,對應於文件描述符請求的events結構體。若是POLLIN事件被設置,則文 件描述符能夠被讀取而不阻塞。若是POLLOUT被設置,則文件描述符能夠寫入而不致使阻塞。這些標誌並非互斥的:它們可能被同時設置,表示這個文件描 述符的讀取和寫入操做都會正常返回而不阻塞。
timeout參數指定等待的毫秒數,不管I/O是否準備好,poll都會返回。timeout指定 爲負數值表示無限超時;timeout爲0指示poll調用當即返回並列出準備好I/O的文件描述符,但並不等待其它的事件。這種狀況下,poll()就 像它的名字那樣,一旦選舉出來,當即返回。
返回值和錯誤代碼
成功時,poll()返回結構體中revents域不爲0的文件描述符個數; 若是在超時前沒有任何事件發生,poll()返回0;失敗時,poll()返回-1,並設置errno爲下列值之一:
EBADF
一個或多 個結構體中指定的文件描述符無效。
EFAULT
fds指針指向的地址超出進程的地址空間。
EINTR
請求的事件以前產生 一個信號,調用能夠從新發起。
EINVAL
nfds參數超出PLIMIT_NOFILE值。
ENOMEM
可用內存不足, 沒法完成請求。 spa