目录
poll:地位不如select,因为select可以跨平台,性能又不如epoll
接口函数
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
fds:事件结构数组,poll函数是通过用户传入的事件结构数组进行监控的,也是轮询监控的方式
         如果要监控一个文件描述符,则组织一个事件结构,传递给poll
         如果要监控多个文件描述符,则组织多个事件结构,放到数组当中,传递给poll
 时间结构:struct pollfd{…}
struct pollfd
{
	int fd;
	short events;
	short revents;
}
fd:待要监控的文件描述符
 events:关心当中文件描述符产生什么事件(可读、可写、异常)
               POLLIN:可读事件
               POLLOUT:可写事件
               如果既关心可读事件也关心可写时间,则将POLLIN | POLLOUT
revents:在poll监控文件描述符的时候,真实产生的事件
                poll在监控的过程当中,文件描述符发生了什么事件,就将该事件放到revents当中
在定义pollfd事件结构体的时候,不需要用户进行初始化,由poll函数进行初始化
小结:
 (1)poll函数引入了事件结构数组的方式,对需要内核监控的文件描述符个数是没有限制了。
 (2)poll在监控事件结构数组的时候,也是采用轮询遍历的方式进行监控,随着监控的事件结构(文件描述符)的增多,监控轮询效率下降。
 (3)用户如果关心一个文件描述符的多种事件(可读、可写、异常),可以直接在同一个事件结构的结构体当中表示,不需要像select一样,添加到不同的事件集合当中去。
nfds:事件结构数组当中有效元素的个数,用来指导poll函数,轮询遍历的范围
 eg:struct pollfd arr[10];
         arr[0].fd = 0;
         arr[0].events = POLLIN;
则:nfds = 1;
timeout:超时时间
                > 0 :带有超时时间的监控,单位:毫秒
                0 :非阻塞的监控方式
                < 0 :阻塞监控的方式
注意区分poll与select的超时时间的传参方式
 select的超时时间参数是struct timeval * timeout,需要传入timeval结构体地址。
 poll的超时时间参数是int timeout,只需要传入数字即可。
返回值:> 0 :监控成功,返回就绪的文件描述符个数
 == 0 :监控超时
 < 0 :监控出错
poll的优缺点
优点:
 (1)引入了事件结构的方式,用户不需要将关心的事件添加到不同的事件集合当中去。
 (2)引用了事件结构的方式,对监控的文件描述符的个数不再限制。
 (3)针对和select对比之后,当一次监控成功之后,下一次再次进行监控的时候,不需要重新添加。
 缺点:
 (1)与select一样也是采用轮询遍历的策略,随着监控的文件描述符增多,轮询效率会下降。
 (2)poll不支持跨平台,只能在linux操作系统下使用
 (3)在调用poll函数的时候,会将用户组织的事件结构数组,拷贝到内核空间,监控成功之后,会将事件结构数组从内核空间拷贝到用户空间,这个举动比较耗费性能。
poll阻塞监控代码
#include <stdio.h>
#include <unistd.h>
#include <poll.h>
//阻塞  监控 0 号文件描述符
int main()
{
    struct pollfd pf;
    pf.fd = 0;
    pf.events = POLLIN; // 关心可读事件
    poll(&pf, 1, -1); // <0 是阻塞监控
    char buf[1024] = {0};
    read(0, buf, sizeof(buf) - 1);
    printf("buf is : %s\n", buf);
    return 0;
}

 
poll非阻塞监控代码
#include <stdio.h>
#include <unistd.h>
#include <poll.h>
//非阻塞监控 0 号文件描述符
int main()
{
    struct pollfd pf;
    pf.fd = 0;
    pf.events = POLLIN;
    while(1)
    {
        int ret = poll(&pf, 1, 0); //0表示非阻塞
        if(ret < 0)
        {
            perror("poll");
            return 0;
        }
        else if(ret == 0)
        {
            printf("poll timeout\n");
            sleep(1);
            continue; //超时,继续监控
        }
        char buf[1024] = {0};
        read(0, buf, sizeof(buf) - 1);
        printf("buf is : %s\n", buf);
    }
    return 0;
}

poll超时时间监控代码
#include <stdio.h>
#include <unistd.h>
#include <poll.h>
//超时时间监控0号文件描述符
int main()
{
    struct pollfd pf;
    pf.fd = 0;
    pf.events = POLLIN;
    while(1)
    {
        int ret = poll(&pf, 1, 1); 
        if(ret < 0)
        {
            perror("poll");
            return 0;
        }
        else if(ret == 0)
        {
            printf("poll timeout\n");
            sleep(1);
            continue;
        }
        char buf[1024] = {0};
        read(0, buf, sizeof(buf) - 1);
        printf("buf is :%s\n", buf);
    }
    return 0;
}










