• 【多路IO复用】select


    select:

    1.select:当被监听的 fd(文件描述符)就绪后会返回,但是我们无法知道具体是哪些 fd 就绪了,只能遍历所有的 fd。通常来说某一时刻,就绪的 fd 并不会很多,但是使用 select 必须要遍历所有的 fd,这就造成了一定程度上的性能损失。select 最多可监听的 fd 是有限制的,32位操作系统默认1024个,64位默认2048

    select函数的API:

    select函数的API
    #include
     /* According to earlier standards */
           #include
           #include
           #include

           int select(int nfds, fd_set *readfds, fd_set *writefds,
                      fd_set *exceptfds, struct timeval *timeout);
    功能: 监听多个文件描述符的属性变化(读,写,异常)
           void FD_CLR(int fd, fd_set *set);
           int  FD_ISSET(int fd, fd_set *set);
           void FD_SET(int fd, fd_set *set);
           void FD_ZERO(fd_set *set);

    参数:
        nfds  : 最大文件描述符+1
        readfds : 需要监听的读的文件描述符存放集合
        writefds :需要监听的写的文件描述符存放集合   NULL
        exceptfds : 需要监听的异常的文件描述符存放集合  NULL
        timeout: 多长时间监听一次   固定的时间,限时等待   NULL 永久监听
        struct timeval {
                   long    tv_sec;         /* seconds */ 秒
                   long    tv_usec;        /* microseconds */微妙
               };

      返回值: 返回的是变化的文件描述符的个数

    

    注意: 变化的文件描述符会存在监听的集合中,未变化的文件描述符会从集合中删除

    select实现原理:

    应用层中父进程通过内核的selsect监听文件描述符缓冲区的变化,内核就会返回给父进程

    以fd_set为例,每次都要从用户态拷贝至内核态,同时还要在内核态进行循环遍历,然后把有事件的响应的文件描述符fd_set返回,又要从内核态拷贝至用户态。用户态拿到这个有事件的文件描述符返回,还要针对返回的描述符进行遍历,才能知道哪个文件描述符对应的Socket可写可读,总共经历了两次遍历,两次拷贝,所以说为什么Select在文件描述符比较多的情况,效率为什么是低下的原因。

    select 的优缺点:

    优点: 跨平台

    缺点:

    文件描述符1024的限制 由于 FD_SETSIZE的限制

    只是返回变化的文件描述符的个数,具体哪个那个变化需要遍历

    每次都需要将需要监听的文件描述集合由应用层符拷贝到内核

    大量并发,少了活跃,select效率低

     

  • 相关阅读:
    OSPF高级特性 —— 被动接口 + 按需链路 + donotage标记
    听GPT 讲Rust源代码--src/librustdoc(2)
    git rebase
    JSP物业服务管理系统myeclipse开发sql数据库BS模式java编程MVC结构
    RocketMQ复制策略和刷盘策略
    k8s单master--测试环境集群搭建
    啊,CET6----六级高频词
    算法——动态规划
    人工智能与机器学习原理精解【1】
    cuda系列详细教程-花絮
  • 原文地址:https://blog.csdn.net/m0_59068776/article/details/130841880