I/O複用----poll

一、poll系統調用

    poll 和select類似,是在指定時間內輪詢一定數量的文件描述符,以測試其中是否有就緒者。

    poll的原型爲:

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

    返回值:

    成功時,返回pollfd結構體中域revents不爲0的文件描述描述符的個數(即數組fds中準備好讀、寫或出錯狀態的那些socket描述符的總數量);如果在超時前沒有事件發生,則返回0;

    失敗,返回-1。

    1),fds參數是一個pollfd結構類型的數組,它指定所有我們感興趣的文件描述符上發生的可讀、可寫和異常等事件。pollfd結構體定義爲:

struct pollfd
{
    int fd;              //文件描述符
    short events;        //註冊的事件
    short revents;       //實際發生的事件,由內核填充
}

    fd成員指定文件描述符;

    events成員告訴poll監聽fd上的哪些事件,它是一系列事件的按位或;

    revents成員則由內核修改,已通知應用程序fd上實際發生了哪些事件。

    poll支持監控的事件類型如下:

 事件描述是否可作爲輸入是否可作爲輸出
POLLIN數據(包括普通數據和優先數據)可讀
POLLRDNORM普通數據可讀 
POLLRDBAND優先級帶數據可讀(linux不支持)
POLLPRI高優先級數據可讀,比如TCP帶外數據
POLLOUT數據(包括普通數據和優先數據)可寫
POLLWRNORM普通數據可讀寫
POLLWRBAND優先級帶數據可寫
POLLRDHUPTCP連接被對方關閉,或者對方關閉了寫操作。它由GNU引入
POLLERR錯誤
POLLHUP掛起。比如管道的寫端被關閉後,讀端描述符上將收到POLLHUP事件
POLLNVAL文件描述符沒有打開
#define POLLIN 0x0001  
#define POLLPRI 0x0002  
#define POLLOUT 0x0004  
#define POLLERR 0x0008  
#define POLLHUP 0x0010  
#define POLLNVAL 0x0020  
  
#define POLLRDNORM 0x0040  
#define POLLRDBAND 0x0080  
#define POLLWRNORM 0x0100  
#define POLLWRBAND 0x0200  
#define POLLMSG 0x0400  
#define POLLREMOVE 0x1000  
#define POLLRDHUP 0x2000  

2),nfds參數指定被監聽事件集合fds的大小、其類型nfds_t的定義如下:

typedef unsigned long int nfds_t;

3),timeout參數指定poll的超時值,單位是毫秒。

    當timeout爲-1時,poll調用將永遠阻塞i,直到某個事件發生;

    當timeout爲0時,poll調用將立即返回;

    當timeout大於0時,爲超時時間。


二、poll和epoll在使用上的區別

    1),如何索引poll返回的就緒文件描述符

int ret = poll(fds, MAX_EVENT_NUMBER, -1);
//必須遍歷所有已註冊文件描述符並找到其中的就緒者(當然也可用ret來優化)
for(int i = 0; i < MAX_EVENT_NUMBER; ++i)
{
    //判斷第i個文件描述符是否就緒
    if(fds[i].revents & POLLIN)
    {
        int sockfd = fds[i].fd;
        //處理sockfd
    }
}

   2), 如何索引epoll返回的就緒文件描述符

int ret = epoll_wait(epollfd, events, MAX_EVENT_NUBER, -1);
//僅遍歷就緒的ret個文件描述符
for(int i = 0; i < ret; i++)
{
    int sockfd = events[i].data.fd;
    //sockfd肯定就緒,直接處理
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章