轮询、select、 epoll
网卡设备对应一个中断号, 当网卡收到网络端的消息的时候会向CPU发起中断请求, 然后CPU处理该请求. 通过驱动程序 进而操作系统得到通知,
一。 阻塞 VS 非阻塞
首先我们来定义流的概念,一个流可以是file,socket,pipe等可以进行I/O操作的内核对象。
我们需要从流中读数据,但是流中还没有数据,典型的例子为,客户端要从socket读如数据,但是服务器还没有把数据传回来,这时候该怎么办?
- 阻塞: 比如你在等快递,但是你不知道快递什么时候过来,而且接下来的事要等快递来了才能做,那你只能一直等到快递来。
- 非阻塞忙轮询。如果用忙轮询的方法,那么你需要知道快递员的手机号,然后每分钟给他电话:你到了没?
很明显一般人不会用第二种做法,浪费话费不说,还占用了快递员大量的时间。
二。了解阻塞是如何进行的
当你操作一个流时,更多的是以缓冲区为单位进行操作,这是相对于用户空间而言。对于内核来说,也需要缓冲区。
假设有一个管道,进程W为管道的写入方,R为管道的读出方。
1.假设一开始内核缓冲区是空的,R作为读出方,被阻塞着。然后首先W往管道写入,这时候内核缓冲区由空的状态变到非空状态,内核就会产生一个
事件告诉R该醒来了,这个事件姑且称之为“缓冲区非空”。
2.但是“缓冲区非空”事件通知R后,R却还没有读出数据;且内核许诺了不能把写入管道中的数据丢掉这个时候,W写入的数据会滞留在内核缓冲区中,
如果内核也缓冲区满了,R仍未开始读数据,最终内核缓冲区会被填满,这个时候会产生一个I/O事件,告诉进程W,你该等等(阻塞)了,我们把这个事件
定义为“缓冲区满”。
3.假设后来R终于开始读数据了,于是内核的缓冲区空了出来,这时候内核会告诉W,内核缓冲区有空位了,你可以从长眠中醒来了,继续写数据了,
我们把这个事件叫做“缓冲区非满”
4.也许事件Y1已经通知了W,但是W也没有数据写入了,而R继续读出数据,知道内核缓冲区空了。这个时候内核就告诉R,你需要阻塞了!,我们
把这个时间定为“缓冲区空”。
这四个情形涵盖了四个I/O事件,缓冲区满,缓冲区空,缓冲区非空,缓冲区非满(注都是说的内核缓冲区,且这四个术语都是我生造的,仅为解释
其原理而造)。这四个I/O事件是进行阻塞同步的根本。
三。轮询
阻塞I/O模式下,一个线程只能处理一个流的I/O事件。如果想要同时处理多个流,
1.多进程(fork)
2.多线程(pthread_create)
3.非阻塞忙轮询、无差别轮询、
while true {
for i in stream[]: {
if i has data
read until unavailable
}
}
我们只要不停的把所有流从头到尾问一遍,又从头开始。这样就可以处理多个流了,但这样的做法显然不好,因为如果所有的流都没有数据,那么只会白白浪
费CPU。这里要补充一点,阻塞模式下,内核对于I/O事件的处理是阻塞或者唤醒,而非阻塞模式下则把I/O事件交给其他对象(select以及epoll)处理。
四。 select
为了避免CPU空转,可以引进了一个代理。这个代理可以同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事
件时,就从阻塞态中醒来,于是我们的程序就会轮询一遍所有的流(于是我们可以把“忙”字去掉了)。代码长这样:
while true {
select(streams[])
for i in streams[] {
if i has data
read until unavailable
}
}
于是,如果没有I/O事件产生,我们的程序就会阻塞在select处。但是依然有个问题,我们从select仅仅知道有I/O事件发生,但却并不知道
是哪几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。
但是使用select,我们有O(n)的无差别轮询复杂度。
五。epoll
可以理解为event poll,不同于忙轮询和无差别轮询,epoll之会把哪个流发生了怎样的I/O事件通知我们。此时我们对这些流的操作都是有意义的。
复杂度降低到了O(k),k为产生I/O事件的流的个数。一个epoll模式的代码大概的样子是:
epollfd = epoll_create()
while true {
active_stream[] = epoll_wait(epollfd)
for i in active_stream[] {
read or write till unavailable
}
}
六。参考
1.文章出处:http://www.zhihu.com/question/20122137
2.epoll API
int epoll_create(int size)
该函数生成一个epoll专用的文件描述符
参数:
size就是你在这个epollfd上能关注的最大socketfd数
返回文件描述符
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
该函数用于控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件
参数:
epfd:由 epoll_create 生成的epoll专用的文件描述符
op:要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 、EPOLL_CTL_MOD 、EPOLL_CTL_DEL
fd:关联的文件描述符
event:指向epoll_event的指针
调用成功返回0,不成功返回-1
int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
该函数用于轮询I/O事件的发生
参数:
epfd: 由epoll_create 生成的epoll专用的文件描述符
epoll_event:用于回传代处理事件的数组
maxevents:每次能处理的事件数
timeout:等待I/O事件发生的超时值;-1相当于阻塞,0相当于非阻塞
返回发生事件数。
轮询、select、 epoll的更多相关文章
- Ajax轮询 select循环输出
弹出层 <include file="Pub:header"/> <style> .del{color:red} .addname{color:#337ab ...
- Nginx反向代理+DNS轮询+IIS7.5 千万PV 百万IP 双线 网站架构案例
原文地址:http://www.jb51.net/article/31844.htm Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,也是一个 ...
- python select epoll poll的解析
select.poll.epoll三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组(在linux中一切事物皆文件 ...
- select&epoll
内核空间和用户空间 现在操作系统都是采用虚拟存储器,那么对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为 4G(2的32次方).也就是说一个进程的最大地址空间为 4G.操作系 ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- 多线程 or I/O复用select/epoll
1:多线程模型适用于处理短连接,且连接的打开关闭非常频繁的情形,但不适合处理长连接.线程模型默认情况下,在Linux下每个线程会开8M的栈空间,在TCP长连接的情况下,以2000/分钟的请求为例,几乎 ...
- select epoll poll
如何理解 Epoll select 和 poll 三种模型,能否用生活中的例子做比喻? 比如说你从某宝下单买了几个东西,这几个东西分别由N个快递员分别给你送过来.在某一时刻,你开始等快递.对于sele ...
- python实现并发服务器实现方式(多线程/多进程/select/epoll)
python实现并发服务器实现方式(多线程/多进程/select/epoll) 并发服务器开发 并发服务器开发,使得一个服务器可以近乎同一时刻为多个客户端提供服务.实现并发的方式有多种,下面以多进 ...
- 五种网络IO模型以及多路复用IO中select/epoll对比
下面都是以网络读数据为例 [2阶段网络IO] 第一阶段:等待数据 wait for data 第二阶段:从内核复制数据到用户 copy data from kernel to user 下面是5种网络 ...
随机推荐
- JVM的回收实现
通过一系列的称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用 ...
- HTML-Audio/Video
简介: 容器:不论是音频还是视频文件,实际上都是容器文件: 视频文件包含了音频轨道.视频轨道和其他一些元数据: 视频文件播放时,音频轨道和视频轨道是绑定在一起:元数据包含了该视频的封面.子标题.字幕等 ...
- ZOJ1516 Uncle Tom's Inherited Land(二分图最大匹配)
一个经典的构图:对格子进行黑白染色,黑白的点分别作XY部的点. 这一题的边就是可以出售的单位面积2的土地,边的端点就是这个土地占用的X部和Y部的两个点. 这样就建好二分图,要求最多土地的答案显然是这个 ...
- LightOJ1033 Generating Palindromes(区间DP/LCS)
题目要计算一个字符串最少添加几个字符使其成为回文串. 一年多前,我LCS这道经典DP例题看得还一知半解时遇到一样的问题,http://acm.fafu.edu.cn/problem.php?id=10 ...
- POJ2288 Islands and Bridges(TSP:状压DP)
求一个图的哈密顿路径的最大权及其路径数.显然状态压缩+DP. dp[v][u][S] 表示从v走到当前顶点 u且走过的顶点集合是S的 最大权值和方案数 这题我用记忆化搜索,从终点开始递归进行,感觉这样 ...
- BZOJ3733 : [Pa2013]Iloczyn
首先将$n$的约数从小到大排序,设$dfs(x,y,z)$表示当前可以选第$x$个到第$m$个约数,还要选$y$个,之前选的乘积为$z$是否可能. 爆搜的时候,如果从$x$开始最小的$y$个相乘也超过 ...
- jquery数组排序学习
前面转载过一片关于js数组的一些基本能操作方法,本文结合实例对数组排序做简要探讨. 首先看一实例,一般涉及到排序都是动态数据,现在我们自己新建一数组进行模拟. html代码: <!DOCTYPE ...
- Tomcat设置默认启动项目及Java Web工程设置默认启动页面
Tomcat设置默认启动项目 Tomcat设置默认启动项目,顾名思义,就是让可以在浏览器的地址栏中输入ip:8080,就能访问到我们的项目.具体操作如下: 1.打开tomcat的安装根目录,找到Tom ...
- java 中文转换成Unicode编码和Unicode编码转换成中文
转自:一叶飘舟 http://blog.csdn.net/jdsjlzx/article/details/ package lia.meetlucene; import java.io.IOExcep ...
- [转]ASP.NET中的forms验证
本文转自:http://www.cnblogs.com/fengzheng126/archive/2012/04/06/2435513.html ASP.NET的安全认证:Windows验证 (默认) ...