困惑

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

     for(;;) {
//通过FD_SET告诉内核你感兴趣的fd
fd_set read_fds;
FD_CLEAR(&read_fds);
FD_SET(fd[],&read_fds);
...
FD_SET(fd[n-],&read_fds);
int maxfdp1 = max(fd[],...,fd[n-]) + ; //获取最大的fd+1 //select采取轮训模式采取
struct timeval tv=;
nready = select(maxfdp1 ,&fd_rds, NULL, NULL,&tv); //有FD可读
if (nready > ) {
for (int i=;i<n;i++) {
if(FD_ISSET(fd[i], &read_fds)) {
recvfrom();
doSomething(); //没有多线程
}
}
}
}

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

因为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从用户态拷贝到内核态,然后又要拷贝出来,效率低。

关于select的困惑的更多相关文章

  1. 最全的ORACLE-SQL笔记

    -- 首先,以超级管理员的身份登录oracle sqlplus sys/bjsxt as sysdba --然后,解除对scott用户的锁 alter user scott account unloc ...

  2. Matplotlib数据可视化(6):饼图与箱线图

    In [1]: from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParam ...

  3. Repository 仓储,你的归宿究竟在哪?(三)-SELECT 某某某。。。

    写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这样的应用层代码,你能接受吗? ...

  4. Select查询执行顺序

    链接:http://blog.jobbole.com/55086/ 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语 ...

  5. 1314: ZZY的困惑

    1314: ZZY的困惑 Time Limit: 2 Sec  Memory Limit: 128 M[Submit][Status][Web Board] Description ZZY有很多爱好~ ...

  6. select poll使用

    select poll使用     2.1. 怎样管理多个连接?“我想同一时候监控一个以上的文件描写叙述符(fd)/连接(connection)/流(stream),应该怎么办?” 使用 select ...

  7. 一个令人困惑的低效SQL

    整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...

  8. left join加上where条件的困惑

    eft join的困惑:一旦加上where条件,则显示的结果等于inner join将where 换成 and 用where 是先连接然后再筛选   用and 是先筛选再连接 数据库在通过连接两张或多 ...

  9. SQLSERVER:PREEMPTIVE_OS_GETPROCADDRESS等待类型的困惑

    SQLSERVER:PREEMPTIVE_OS_GETPROCADDRESS等待类型的困惑 翻译自:http://troubleshootingsql.com/2011/07/20/preemptiv ...

随机推荐

  1. nc简单使用

    1.安装 2.运行

  2. 防止sshd服务被暴力破解

    方法有很多种,这里介绍两种. (1).配置安全的shhd设置 不允许root用户直接登录到系统,添加一个普通用户,必要时再切换到root用户. 修改默认端口号. 不允许密码登录,只能通过密钥登录系统. ...

  3. <c:if test="${uns ne ‘admin’}">

    类别 运算符 算术运算符 + . - . * . / (或 div )和 % (或 mod ) 关系运算符 == (或 eq ). != (或 ne ). < (或 lt ). > (或 ...

  4. delphi type

    声明: 1. type Name = Existing type; 2. type Name = type Existing type; 3. type Name = (EnumValue1 [=va ...

  5. js 匿名函数 js-函数定义方法

    1.任何函数都是有返回值的,没有返回值的,在某些语言里称之为过程例如PL/SQL 2.js中的函数如果没有return 关键字指明给出的返回值,那么当调用完函数后,会返回“undefined" ...

  6. ffmpeg 使用 gdb 调试相关技巧

    本文说明了,在ffmpeg二次开发或调用库的过程,如何借助于ffmpeg源码进行调试. 注:ffmpeg版本是4.0. 1. 编写代码 编写将pcm数据转换为mp2的代码 pcm_to_mp2.c # ...

  7. MFC中使用ADO进行数据库操作

    参考FROM:http://hi.baidu.com/sunkanghome/item/e1fda510b3186359f1090ee2 数据库与数据库编程: 当前各种主流数据库有很多,包括Oracl ...

  8. 洛谷 题解 P2676 【超级书架】

    题解 P2676 [超级书架] 这题就只是一个从大到小的排序而已,用"sort"函数 再用"while"判断奶牛塔的高度是否比书架高度要高 送上代码: #inc ...

  9. 【leetcode算法-简单】9. 回文数

    [题目描述] 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121输出: true示例 2: 输入: -121输出: false解释: ...

  10. lua table 的操作(四)

    table在前面作过介绍,它是一种关联数组,这种关联指的是可以设置各类类型的key来存储值. 1.table 间的数据传递 -- 为 table a 并设置元素,然后将 a 赋值给 b,则 a 与 b ...