关于select的困惑
困惑
首先,我知道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的困惑的更多相关文章
- 最全的ORACLE-SQL笔记
-- 首先,以超级管理员的身份登录oracle sqlplus sys/bjsxt as sysdba --然后,解除对scott用户的锁 alter user scott account unloc ...
- Matplotlib数据可视化(6):饼图与箱线图
In [1]: from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParam ...
- Repository 仓储,你的归宿究竟在哪?(三)-SELECT 某某某。。。
写在前面 首先,本篇博文主要包含两个主题: 领域服务中使用仓储 SELECT 某某某(有点晕?请看下面.) 上一篇:Repository 仓储,你的归宿究竟在哪?(二)-这样的应用层代码,你能接受吗? ...
- Select查询执行顺序
链接:http://blog.jobbole.com/55086/ 很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语 ...
- 1314: ZZY的困惑
1314: ZZY的困惑 Time Limit: 2 Sec Memory Limit: 128 M[Submit][Status][Web Board] Description ZZY有很多爱好~ ...
- select poll使用
select poll使用 2.1. 怎样管理多个连接?“我想同一时候监控一个以上的文件描写叙述符(fd)/连接(connection)/流(stream),应该怎么办?” 使用 select ...
- 一个令人困惑的低效SQL
整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...
- left join加上where条件的困惑
eft join的困惑:一旦加上where条件,则显示的结果等于inner join将where 换成 and 用where 是先连接然后再筛选 用and 是先筛选再连接 数据库在通过连接两张或多 ...
- SQLSERVER:PREEMPTIVE_OS_GETPROCADDRESS等待类型的困惑
SQLSERVER:PREEMPTIVE_OS_GETPROCADDRESS等待类型的困惑 翻译自:http://troubleshootingsql.com/2011/07/20/preemptiv ...
随机推荐
- MSE, MAE, Huber loss详解
转载:https://mp.weixin.qq.com/s/Xbi5iOh3xoBIK5kVmqbKYA https://baijiahao.baidu.com/s?id=16119517755261 ...
- 关于对多层嵌套的json字符串取目标值的问题
import java.util.HashMap;import java.util.Iterator;import java.util.Map;import net.sf.json.JSONObjec ...
- 类型TTreeView.items.add 与 TTreeView.items.addchild有何区别?(10分)
我看了书上例子,好象两者都可以实现treeview中的node 的构建. addchild是给当前的node建一个子node,它比当前node要向右缩进几格add建立同级的node,不缩进 aNode ...
- Spring Security(3):配置与自动配置的介绍及源码分析
基于注解的配置(Java Configuration)从Spring Security 3.2开始就已经支持,本篇基于Spring boot注解的配置进行讲解,如果需要基于XML配置(Security ...
- Ocelot 配置参数
Downstream是下游服务配置 UpStream是上游服务配置 Aggregates 服务聚合配置 ServiceName, LoadBalancer, UseServiceDiscovery 配 ...
- Docker Java程序镜像制作
Docker Java程序镜像制作 制作前的准备 jre:不需要完整的jdk,jre即可,到Oracle进行下载即可,下载链接,根据自己的情况进行选择,这里选择jre-8u221-linux-x64. ...
- Had I not seen the Sun(如果我不曾见过太阳)
Had I not seen the Sun by Emily Dickinson Had I not seen the Sun I could have borne the shade But Li ...
- solr7.2.1+tomcat8.5.37+jdk8安装配置
软件下载 solr7.2.1:http://archive.apache.org/dist/lucene/solr/7.2.1/solr-7.2.1.tgz 注意是.tgz结尾的文件,而不是.zip ...
- centos7服务搭建常用服务配置之二:Rsync+sersync实现数据实时同步
目录 1.RSYNC数据备份 1.1 rsync服务简介 1.2 rsync特点和优势 1.3 rysnc运行模式简介 1.4 数据同步方式 2 Rsync实验测试 2.1 实验环境说明 2.2 服务 ...
- kafka producer interceptor拦截器(五)
producer在发送数据时,会经过拦截器和序列化,最后到达相应的分区.在经过拦截器时,我们可以对发送的数据做进步的处理. 要正确的使用拦截器需要以下步骤: 1.实现拦截器ProducerInterc ...