• poll


    函数原型

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

    参数解释

    • fds:指向一个结构体数组的第0个元素的指针,每个数组元素都是一个struct pollfd结构,用于指定测试某个给定的fd的条件
    • nfds:表示fds结构体数组的长度
    • timeout:表示poll函数的超时时间,单位是毫秒

    函数功能

    监视并等待多个文件描述符的属性变化

    函数返回值

    • 返回值小于0,表示出错
    • 返回值等于0,表示poll函数等待超时
    • 返回值大于0,表示poll由于监听的文件描述符就绪返回,并且返回结果就是就绪的文件描述符的个数

    pollfd结构

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

    成员变量说明:

    • fd:每一个 pollfd 结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示 poll() 监视多个文件描述符。
    • events:表示要告诉操作系统需要监测fd的事件(输入、输出、错误),每一个事件有多个取值
    • revents:revents 域是文件描述符的操作结果事件,内核在调用返回时设置这个域。events 域中请求的任何事件都可能在 revents 域中返回。

    events&revents的取值如下:

    注意:
    每个结构体的 events 域是由用户来设置,告诉内核我们关注的是什么,而 revents 域是返回时内核设置的,以说明对该描述符发生了什么事件
    这些宏相当于每一个占用一个比特位,所以,如果我们要进行设置两个事件,就使用|操作,另外,当我们去查看事件是否发生的时候,这个时候我们可以使用revents&事件,如果事件发生了,那么结果大于1。

    poll 特点

    poll优点

    • poll里包含了要监视的event和发生的event,使读写分离,每次循环不需要重新设置,接口使用方便
    • poll的文件描述符数量不受限制,一个数组可以开多大,就可以有多少个文件描述符,换句话说,只要内存足够,想开多少就开多少,但是太多了性能也会下降

    poll缺点

    • 当文件描述符很多的时候,依旧需要使用轮询的方式来获取文件描述符,效率低
    • 每次调用poll也需要吧大量的pollfd结构从用户态拷贝至内核中,文件描述符很多事,效率也会很低
    • 同时连接的大量客户在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会现行下降

    示例

    用poll监视标准输入:

    #include <stdio.h>
    #include <unistd.h>
    #include <poll.h>
     
    int main()
    {
        struct pollfd fds;
        fds.fd = 0;
        fds.events = POLLIN;
        while(1)
        {
            int ret = poll(&fds,1,1000);
            if(ret < 0)
            {
                perror("poll");
                continue;
            }
            if(ret == 0)
            {
                printf("timeout...
    ");
                continue;
            }
            if(fds.revents == POLLIN)
            {
                char buf[1024] = {0};
                read(0,buf,sizeof(buf)-1);
                printf("stdin: %s
    ",buf);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    SpringMVC常用注解
    在Java 中,如何跳出当前的多重嵌套循环?
    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    查看远程库信息(git remote的用法)
    webpack和gulp的比较
    git pull 和git fetch的区别
    什么是性能优化?
    第一阶段的任务及燃尽图(第五天)
    第一阶段的任务及燃尽图(第二天)
    第一阶段的任务及燃尽图(第一天)
  • 原文地址:https://www.cnblogs.com/chay/p/10794304.html
Copyright © 2020-2023  润新知