关于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 ...
随机推荐
- uni-app 使用 iconfont 图标 自定义图标
uni-app 的uni-ui 的 Icon 图标组件,裡面的图标只是移动端常见的图标,对于一些其他需求所要显示的图标,这个是完全不够用.那么怎么办?模仿它的组件,用阿里巴巴图标矢量库的图标,自己定义 ...
- 使用IDEA来实现分支代码合并
使用beyond comapre进行分支代码的合并是常用的方法,同时比较2个分支的代码,选择需要和入的代码后再提交即可. 如果是不能使用beyond comapre的情况下,使用IDEA的分支比较功能 ...
- 【leetcode】500_Keyboard Row
problem 500. Keyboard Row 题意:判断给出的某个单词是否可以使用键盘上的某一行字母type得到: 注意大小写的转换: solution1: 使用set保存三行字符,查看每个字符 ...
- 【IDEA】格式化代码技巧汇总
1.格式化 Java 代码 快捷键:Ctrl+Alt+L 2.格式化 Mapper 文件中的 SQL 关联到数据库,让 IDEA 认识你的 SQL.如何关联?选择右侧的database,添加数据库即可 ...
- MySQL中的日期和时间:使用和说明,以及常用函数
1.首先需要注意: 1.1 MySQL中把日期和时间是分开的. 以字符串2007-12-31 00:59:59为例: 日期部分:2007-12-31.这部分也可以叫做一个日期表达式. 时间部分:00: ...
- golang的定时器NewTimer、NewTicker使用
package main import ( "fmt" "sync" "time" ) /** *ticker只要定义完成,从此刻开始计时, ...
- solr的使用
一,下载,安装 https://lucene.apache.org/solr/ 二, mac下使用 下载二进制包后,解压 step 1 进入solr目录: cd solr-8.2.0 step 2 进 ...
- Maven仓库介绍以及私服搭建
1 什么是Maven? 1.1 Maven的概念 Maven主要服务于基于Java平台的项目构建.依赖管理和项目信息开发,它是一个异常强大的构建工具,能够帮助我们自动化构建过程,从清理.编译.测试 ...
- python+pycharm+django admin css样式出问题
最近打算学习一下Python,基础知识有了大概的了解,想上手搞搞东西. 我用的python 3.5+pycharm+django 1.11.2 在使用Django,打开127.0.0.1:8000/a ...
- mydumper,myloader原理及实战
mydumper 特性 (1)多线程备份(和mysqlpump的多线程不同,mysqlpump多线程备份的粒度是表,mydumper多线程备份的粒度是行,这对于备份大表特别有用)(2)因为是多线程逻辑 ...