【Linux编程】IO复用之poll详解

poll系统调用

poll系统调用和select非常相似,关于select的详解可以在本博客中找到,poll也是在一定时间内轮询监听用户感兴趣的文件描述符上的可读、可写和异常事件。

poll系统调用原型

#include
int poll(struct pollfd fdset[], nfds_t nfds, int timeout);

1)fdset参数是一个pollfd结构体类型的数组,其定义如下:

struct pollfd{
    int fd;         /*文件描述符,如果小于0。这个文件描述符将会被进程忽略*/
    short events;   /*注册的事件,即感兴趣的事件。可以是一个事件,也可以是多个事件的按位或*/
    short revents; /*实际发生的事件,由内核来赋值。需要与某种类型的事件按位与来确定某种事件是否发生*/
};

这个结构体指定了我们感兴趣的文件描述符上发生的可读、可写和异常事件。
与select不同,poll不是为每个事件构造一个描述符集合,而是用一个pollfd结构体数组来指定用户感兴趣的文件描述符及其事件。
poll事件类型如下表:
【Linux编程】IO复用之poll详解_第1张图片
自Linux内核2.6.17开始,GUN为poll系统调用增加了一个POLLRDHUP事件,它在socket上接收到对方关闭连接的请求之后触发,使用POLLRDHUP时,需要在代码最开始处定义 _GUN_SOURCE。
当然我们也可以通过read来判断对方是否关闭了连接,当read返回0时,表示对方请求关闭连接。
2)nfds参数指定了pollfd结构体数组fdset的大小,nfds_t是一个无符号长整型类型:
typedef unsigned long int nfds_t;
3)timeout参数指定poll的超时时间,单位是毫秒。
当timeout==-1时:永久等待,直到指定的描述符有事件发生或捕捉到信号时返回。
当timeout==0时:不等待,测试完所有描述符后立即返回。
当timeout>0时:等待指定的毫秒,在超时时间内,当指定的描述符有事件发生或捕捉到信号时返回。

poll返回值

poll的返回值含义与select相同。
1)返回-1,表示出错,比如在等待期间捕捉到一个信号。
2)返回0,表示在超时时间内没有描述符准备好。
3)返回一个正值,表示已经准备好的描述符的数量。

poll函数的一个小实例

#include 
#include 
#include 
#include 
int main(){
    struct pollfd fdset[1];
    fdset[0].fd = 0;
    fdset[0].events = POLLIN;
    int ret;
    char buf[100];
    while(1){
        ret = poll(fdset, 1, -1);
        if(fdset[0].revents & POLLIN){
            ret = read(0, buf, 100);
            printf("读取到%d个字节的数据%s", ret, buf);
        }
    }
    return 0;
}

这个小实例主要是监听标准输入上的POLLIN事件,当我们在键盘上敲入数据时,会触发POLLIN事件,表示有数据可读,然后poll返回。由内核修改的fdset[0].revents与POLLIN相与判断是否发生了POLLIN事件,当为真则发生,就可以读取键盘上的输入数据了。

你可能感兴趣的:(Linux网络编程)