转--select/poll/epoll到底是什么一回事
面试题:说说select/poll/epoll的区别。
这是面试后台开发时的高频面试题,属于网络编程和IO那一块的知识。Android里面的Handler消息处理机制的底层实现就用到了epoll。
为此,我在Google上看了很多相关文章,才大概搞懂是怎么一回事。
背景知识
文件描述符fd
文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。在Linux系统中,流在内核中可以表示成文件的形式。
IO模型
IO可以理解成对流的操作。
一般对于一个read操作发生时,它会经历两个阶段。
第一个阶段是等待数据准备。
第二个阶段是真正读取的过程,将数据从内核缓冲区拷贝到用户进程缓冲区中,
而五种常见的IO模型也是围绕这两个阶段来区分的。
同步模型(synchronous IO)
阻塞IO(bloking IO)
非阻塞IO(non-blocking IO)
多路复用IO(multiplexing IO)
信号驱动式IO(signal-driven IO)
异步IO(asynchronous IO)
其中,IO多路复用就是一种机制,实现一个进程可以监视多个描述符,一旦某个描述符就绪,就能够通知程序进行相应的读写操作。IO多路复用相比于多线程的优势在于系统的开销小,系统不必创建和维护进程或线程,免去了线程或进程的切换带来的开销。而操作系统支持IO多路复用的系统调用有select,poll和epoll。
select
先来看看select的函数声明:
int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
1
fd_set是表示文件描述符集合的数据结构。readfds,writefds和exceptfds分别对应三类文件描述符集。当select被调用时,内部逻辑如下:
将3个fd集copy到内核,这里限制了fd最大数量为1024
线程阻塞,直到超时或内核检测到有fd可读或可写,内核会通知监控者select,select返回可读或可写的fd总数
那么用户进程如何找到可读可写的fd呢?select会将之前传递给内核的fd集从内核copy到用户进程。用户进程通过遍历的方式找到可读可写的fd。
缺点:
copy次数过多,而且每次调用select方法都要进行fd集的copy操作
select监控fd数量有限
用户进程通过遍历的方式找到可读写的fd,时间复杂度为o(n),IO效率随着fd数量增多而线性下降
poll
先来看看poll的函数声明:
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
1
pollfd是表示文件描述符集合的数据结构。
struct pollfd {
int fd; //文件描述符
short events; //监视的请求事件
short revents; //已发生的事件
};
1
2
3
4
5
poll与select差不多,但poll的pollfd没有最大数量的限制,可是IO效率依旧没有提升orz。
epoll
select/poll都只有一个方法,而epoll的操作过程有3个方法,分别是epoll_create(), epoll_ctl(),epoll_wait()。
epoll_create()
int epoll_create(int size);//用于创建一个epoll的句柄,size是指监听的描述符个数。
1
该方法会在内核创建专属于epoll的高速cache区,并在该缓冲区建立红黑树和就绪链表,用户态传入的文件句柄将被放到红黑树中。
epoll_ctl()
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
1
该方法对epoll_create()所创建的内核cache区进行操作的,操作对象是需要监听的fd。
比如,把要监听的fd注册到cache内,那么epoll_ctl()会将fd插入到红黑树中,并向内核注册了该fd的回调函数。内核在检测到某fd可读可写时则调用该回调函数,而回调函数的工作是将fd放到就绪链表。
epoll_wait()
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
1
epoll_wait只需监控就绪链表,如果就绪链表有fd,则表示该fd可读可写,并返回给用户态(少量的copy);
该函数返回需要处理的事件数目,如返回0表示已超时。
小结
执行epoll_create时,在创建了红黑树和就绪链表。执行epoll_ctl时,如果增加fd,则检查在红黑树中是否存在,存在立即返回,不存在则添加到树上,然后向内核注册回调函数,用于当中断事件到来时向准备就绪链表中插入数据。执行epoll_wait时返回就绪链表里的数据即可。
因此,epoll比select和poll高效的原因是:
减少了用户态和内核态之间文件句柄的copy
降低了在文件句柄集中查找的时间复杂度。用红黑树维护fd集,可以将查找fd的时间复杂度降为o(logn)。
参考
https://www.zhihu.com/question/20122137
http://www.jianshu.com/p/dfd940e7fca2#
http://gityuan.com/2015/12/06/linux_epoll/
转--select/poll/epoll到底是什么一回事的更多相关文章
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程
1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...
- Linux IO模式以及select poll epoll详解
一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...
- select/poll/epoll on serial port
In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port t ...
- Linux下select&poll&epoll的实现原理(一)
最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录.其基本的原理是相同的,流程如下 先依次调用fd对应的st ...
- Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...
- 多进程、协程、事件驱动及select poll epoll
目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...
- Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO
本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO 1. 多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...
- select,poll,epoll的归纳总结区分
Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd标志位 ...
- 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】
下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...
随机推荐
- 脚本自动封掉并发数过高的 IP
防止扫描器对服务器恶意扫描,可以对 iptables 规则做了比较严格的配置. 以下配置可作为参考: #lo -A INPUT -i lo -j ACCEPT -A OUTPUT -o lo -j A ...
- [WC2014]紫荆花之恋(动态点分治+替罪羊思想)
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
- 20165223 学习基础和C语言基础调查
一.学习基础 1. 我所擅长的技能 从小我就对新鲜事物抱有浓厚的兴趣,因此多年来培养了许多爱好,对感兴趣的诸如绘画方面的国画.油画.素描.漫画等:音乐方面的钢琴.吉他.架子鼓等:运动方面的滑板.溜冰. ...
- Python学习day4 数据类型Ⅱ(列表,元祖)
day4 知识补充&数据类型:列表,元祖 1.知识补充 1.编译型/解释型 编译型:在代码编写完成之后编译器将其变成另外一个文件教给你算计执行. 代表语言:Java,c,c++ ,c#, Go ...
- height、clientHeight、offsetHeight、scrollHeight、height()、 innerHeight()、outerHeight()等的区别
1.height height是css属性,这个属性定义元素内容区的高度,在内容区外面可以增加内边距.边框和外边距. 当 box-sizing: content-box 时,高度应用到元素的内容框. ...
- 【洛谷P1903】数颜色
题目大意:给定一个长度为 N 的序列,每个点有一个颜色.现给出 M 个操作,支持单点修改颜色和询问区间颜色数两个操作. 题解:学会了序列带修改的莫队. 莫队本身是不支持修改的.带修该莫队的本质也是对询 ...
- 【CF131D】Subway
题目大意:给定一棵 N 个节点的基环树,求各个点到环的最小距离. 题解:除了找环的必须参数之外,对每个点维护一个 fa 即可. 代码如下 #include <bits/stdc++.h> ...
- 第五篇:数据备份、pymysql模块
http://www.cnblogs.com/linhaifeng/articles/7525619.html#_label3 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们 ...
- Vue+koa2开发一款全栈小程序(3.vue入门、Mpvue入门)
1.Vue-cli 1.新建一个vue项目 打开cmd 官方命令行工具 npm install -g vue-cli //安装脚手架 cd到你想要存放demo的目录下,然后 vue init webp ...
- 第十六节、基于ORB的特征检测和特征匹配
之前我们已经介绍了SIFT算法,以及SURF算法,但是由于计算速度较慢的原因.人们提出了使用ORB来替代SIFT和SURF.与前两者相比,ORB有更快的速度.ORB在2011年才首次发布.在前面小节中 ...