转--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多路复用框架, ...
随机推荐
- 自学华为IoT物联网_02 常见物联网通信技术
点击返回自学华为IoT物流网 自学华为IoT物联网_02 常见物联网通信技术 两类技术: 有线通信技术 无线通信技术 一. 有线通信技术 1.1 物联网有线技术介绍及对比 ETH 主要用于支持以太网标 ...
- Android assets res 文件夹的区别
大家都知道建立一个Android项目后会产生assets与res的两个文件夹,理论上他们都是存放资源的文件夹,那么他们到底有什么区别呢? 1.assets:不会在R.java文件下生成相应的标记,存放 ...
- Java简单工厂模式(SimpleFactoryMode)
何为简单工厂模式? 由一个工厂类根据传入的参数,动态创建并返回相应的具体的实例! 三个构成元素: 1.工厂类 2.抽象产品 3.具体产品 优点: 1.提高扩展性 2.隐藏具体的实现类,并不需要知道产品 ...
- Swarm部署集群
swarm-manager 是 manager node,swarm-worker是 worker node.所有节点的 Docker 版本均不低于 v1.12.在master上 docker swa ...
- 使用jvisualVm监控本地和远程的jvm
jvisualVm是jdk自带的可视化监控工具,功能很强大,可安装各种扩展插件.本篇不打算讲解如果使用详细的功能,只讲在windows环境怎么监控本地和远端(一般是无界面的linux系统)的java进 ...
- luogu4159 迷路 (矩阵加速)
考虑如果只有距离为1的边,那我用在时间i到达某个点的状态数矩阵 乘上转移矩阵(就是边的邻接矩阵),就能得到i+1时间的 然后又考虑到边权只有1~9,那可以把边拆成只有距离为1的 具体做法是一个点拆成9 ...
- webpack入门(四)webpack的api 2 module
接着介绍webpack的module. module Options affecting the normal modules (NormalModuleFactory) 这些选项影响普通的模块 m ...
- 编写高质量代码:改善Java程序的151个建议 --[26~36]
提防包装类型的null值 public static int testMethod(List<Integer> list) { int count = 0; for (Integer i ...
- Electron入门笔记(二)-快速建立hello world
官方的文档我没有看懂,看了不少别人的博客和文章,终于慢慢看懂了如何快速的建立一个Electron app demo,前一篇文章不是使用官方快速搭建的,而且还出了小问题,所以去撸了一遍quick-sta ...
- NPOI的一些基本操作
1,创建一个Excel //创建一个工作簿 XSSFWorkbook workbook = new XSSFWorkbook(); //创建一个页 ISheet sheet = workbook.Cr ...