• 关于select的困惑


    困惑

    首先,我知道select是IO复用。以UDP为例,select流程大体如下:

     1     for(;;) {
     2         //通过FD_SET告诉内核你感兴趣的fd
     3         fd_set read_fds;
     4         FD_CLEAR(&read_fds);
     5         FD_SET(fd[0],&read_fds);
     6         ...
     7         FD_SET(fd[n-1],&read_fds);
     8         int maxfdp1 = max(fd[0],...,fd[n-1]) + 1; //获取最大的fd+1
     9 
    10         //select采取轮训模式采取
    11         struct timeval tv=0;
    12         nready = select(maxfdp1 ,&fd_rds, NULL, NULL,&tv);
    13         
    14         //有FD可读
    15         if (nready > 0) {
    16             for (int i=0;i<n;i++) {
    17                 if(FD_ISSET(fd[i], &read_fds)) {
    18                     recvfrom();
    19                     doSomething();    //没有多线程
    20                 }
    21             }
    22         }
    23     }

    但是网上很多人都说这个框架使得服务端实现了并发。我很好奇的是,这个并发是怎么实现的?

    因为select返回大于0后,开始检查read_fds,看是哪些FD已经可读。比如fd1和fd5可读了,我肯定先处理fd1的数据,这时候我可能处理的时间较长(比如说1秒),那么fd5就是要1s后才能处理,这样怎么就并发了呢?要是有100个FD可读,每个fd的数据都花了1秒处理,那么这个框架性能岂不是很差。

    注意:我是想说在dosomething()没有多线程的情况下,不就是顺序执行的,一个一个FD按个处理。可能我对并发的理解也不到位,希望有高手能帮我答疑解惑。非常感谢。

    解惑

    我对并发有误解。并发和并行是不一样的。并行指的是同一时刻多个进程或线程同时处理。并发指的是一段时间内(比如30s)处理多个任务或fd。这样的话,疑惑就解开了。

    题外话:IO复用究竟是什么

    IO复用的本质是内核级别的对多个fd进行轮询,然后哪个好了就通知用户代码。这么的优点是,如果没有IO复用,用户需要自己去轮询哪个fd准备好了,亦或更糟糕一点,一个线程阻塞等待一个fd。因此IO复用只是在fd是否就绪这个问题上帮助用户代码,所谓就绪包括请求到来。但是真正处理请求。但是真正处理请求,是由用户自己的工作进程或工作线程来处理的,如果同时请求量过大,超过了单机处理的能力,那么需要我们自己设计多线程或者线程池排队或者分流机制,这个和IO复用不冲突,也没有关系。

    select的缺点

    老生长谈的问题了。

    1、最大并发数限制:使用32个整数的32位,即32*32=1024来标识fd,虽然可修改,但是有以下第二点的瓶颈;

    2、效率低:每次都会线性扫描整个fd_set,集合越大速度越慢;

    3、内核/用户空间内存拷贝问题。把fd_set从用户态拷贝到内核态,然后又要拷贝出来,效率低。

  • 相关阅读:
    (Linux基础学习)第五章:Linux中的screen应用
    (Linux基础学习)第四章:Linux系统中的日期和时间介绍和ntpdate命令
    (Linux基础学习)第三章:terminal与shell的简介和修改命令提示符颜色
    (Linux基础学习)第二章:CentOS7.4安装教程
    (Linux基础学习)第一章:科普和Linux系统安装
    Linux基础入门 第一章:Linux环境搭建——Redhat 6.4图文安装教程
    结合Zabbix与Ansible打造自动化数据库监控体系
    Jenkins Tomcat 环境搭建
    SVN 服务器的搭建
    Dockerfile 创建redis容器
  • 原文地址:https://www.cnblogs.com/howo/p/8485903.html
Copyright © 2020-2023  润新知