【UNIX】select、poll、epoll学习
三者都是UNIX下多路复用的内核接口,select是跨平台的接口,poll是systemV标准,epoll是linux专有的接口,基于poll改造而成。
select
函数原型:
int select (int n,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
select通过系统调用监视多个文件描述符的数组,select返回后,就绪的文件描述符会被修改标志位,使得进程可以获得准备就绪的文件描述符并继续I/O操作。
select目前的优点就是几乎所有的系统都支持select,缺点是最大只能监听1024个文件描述符,想监听超过1024个文件描述符时需要手动修改FD_SETSIZE大小,但这样活造成网络I/O性能下降;或者创建多进程,每个进程监听1024个文件描述符,这样会导致程序复杂度增加。
select的第一个参数n需要程序员自己处理,n为所有集合中最大的文件描述符值+1;select的第二个参数readfds列举的文件描述符被监视是否有可供读取的数据;select的第三个参数writefds列举的文件描述符被监视是否写入完成而不阻塞;select的第三个参数exceptfds列举的文件描述符被监视是否异常或者无法控制的数据是否可用(这些状态仅用于套接字);当文件描述符列表设置为NULL时该类文件描述符不被监视。select的第四个参数timeout用于设置超时时长,当select经过了timeout时长后仍然没有可用的文件描述符也将返回;select的返回值代表了当前可用的文件描述符的数量,范围为0-1024,当超时返回时返回值为0,其他时候是1-1024区间的值。
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* 10E-6 second */
};
如果select的timeout参数不为NULL,即便没有文件描述符准备好I/O,也会在等待ty_sec秒和ty_usec微秒后select返回,timeout在不同系统中的处理是不同的,最好每次调用select前设置一次。
向select监视的文件描述符集合中添加或者删除文件描述符通常采用系统定义的宏进行
FD_ZERO:将集合清空
FD_SET:向集合中添加一个文件描述符
FD_CLR:从集合中删除一个文件描述符
FD_ISSET :指定的文件描述符是否在集合中
能够放进fd_set中的最大的文件描述符值是1024,这个值是由FD_SETSIZE决定的。
select调用成功后非NULL的文件描述符集合将被修改,集合中将只剩下准备好的文件描述符,通过FD_ISSET轮询所有集合确定准备好I/O的文件描述符。
select的缺点:在于维护的存储文件描述符的数据结构需要在内核空间和用户空间来回复制,随着文件描述符数量的增加,复制所花费的开销也线性增长; 由于网络延迟,很多socket会处于非活跃状态,但select也会对其进行一次扫描。这两个缺点导致select的效率随文件描述符数量降低,在处理大量fd非活跃的集合时效率降低。
select仅支持水平触发(Level Triggered):即一个fd被返回可用后,如果没有对该fd进行I/O操作,那么下次select返回时仍然报告该fdI/O可用。
poll
poll和select本质上类似,但不存在最大文件描述符数量的限制,poll和select存在一样的缺点:维护的文件描述符数据结构在内核空间和用户空间来回拷贝,效率随监视的文件描述符数量而下降。
int poll (struct pollfd *fds, unsigned int nfds, int timeout);
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};
poll中的每一个pollfd指明一个被监视的文件描述符,nfds指明最大监视的文件描述符数,timeout代表了超时时长,单位为毫秒。
pollfd结构体的fd是文件描述符;events是要监视的事件掩码;revents是被监视的文件描述符操作结果事件掩码,内核在返回时设置这个域。每一个events都可能在revents中被返回。
epoll
epoll是linux2.6以后出现的内核直接支持的方法,具有了select和poll的一切优点,被认为是linux2.6下最优秀的I/O就绪通知方式。
epoll可以支持水平触发(Level Triggered)和边缘触发(Edge Triggered,当文件描述符就绪时仅通知进程一次,即使进程没有对其进行I/O操作,以后也不会再通知),边缘触发方式适合高速I/O,但编程实现较为复杂。
epoll同样只告知那些准备就绪的文件描述符,当调用epoll_wait成功返回时,返回值代表准备就绪的文件描述符,此时epoll一个指定的数组中取出相应数量的文件描述符即可,epoll采用了文件映射技术(mmap),内核和用户态访问同一段内存,避免了文件描述符在内核和用户态之间的互相复制;epoll还采用了基于事件的就绪通知方式,epoll事先通过epoll_ctl注册一个文件描述符,一旦某个文件描述符就绪时,系统会采用类似于callback的机制迅速激活这个文件描述符,当进程调用epoll_wait便得到通知。
epoll的优点有可监视的文件描述符数量等于系统可打开的最大文件描述符;epoll的效率不随监视的文件描述符数量增加而线性下降;epoll通过文件映射减少了内核和用户态数据复制开销。
函数原型
int epoll_create(int size);
创建一个epoll句柄,指定要监听的文件描述符数量
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
对epoll句柄进行操作
epfd指定epoll句柄;
op为指定的操作EP_CTL_ADD(注册新的句柄到epoll);EP_CTL_MOD(修改已经注册的文件描述符的监听事件);EP_CTL_DEL(删除一个已经注册的fd)
fd为要注册的文件描述符
event为监听的事件
epoll_event结构如下:
struct epoll_event {
__uint32_t events; /*Epoll events*/
epoll_data_t data; /*User data variable*/
}
events可以用以下几个宏的集合
EPOLLIN:当前文件描述符可读
EPOLLOUT:当前文件描述符可以写
EPOLLPRI:当前文件描述符有紧急数据可以读(应该表示有带外数据到来)
EPOLLERR:当前文件描述符发生错误
EPOLLHUP:对应的文件描述符被挂断
EPOLLET:将EPOLL设置为边缘触发模式
EPOLLONESHOT:只监听一次事件,当完成一次监听以后还需要监听该描述符的话需要再次加入到EPOLL队列中。
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
等待事件的发生,类似select返回。
后记
本次学习笔记基于网络搜索,非原创,也没有用到select、poll、epoll,可以说从零开始学,难免有些浅薄,待以后有了实际经验会进行补充。
补充
IPC和select、poll、epoll能否同时使用?通常不可以,这会带来不少麻烦,因为IPC的实现方式并不是文件描述符,如果需要同时使用IPC和多路复用(select、poll、epoll),可以采用fork子进程,然后父进程和子进程采用IPC或管道通信,其中一个进程使用多路复用技术监控文件描述符。
多路复用技能着重处理的文件描述符是socket、管道、伪终端(pty)、终端设备(tty)等系统文件描述符,对普通文件描述符不起作用。
【UNIX】select、poll、epoll学习的更多相关文章
- Java IO 学习(二)select/poll/epoll
如上文所说,select/poll/epoll本质上都是同步阻塞的,但是由于实现了IO多路复用,在处理聊天室这种需要处理大量长连接但是每个连接上数据事件较少的场景时,相比最原始的为每个连接新开一个线程 ...
- 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!
系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...
- select/poll/epoll on serial port
In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port t ...
- 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三者之间的比较
一.概述 说到Linux下的IO复用,系统提供了三个系统调用,分别是select poll epoll.那么这三者之间有什么不同呢,什么时候使用三个之间的其中一个呢? 下面,我将从系统调用原型来分析其 ...
- 转--select/poll/epoll到底是什么一回事
面试题:说说select/poll/epoll的区别. 这是面试后台开发时的高频面试题,属于网络编程和IO那一块的知识.Android里面的Handler消息处理机制的底层实现就用到了epoll. 为 ...
- IO多路复用select/poll/epoll详解以及在Python中的应用
IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...
- [serial]基于select/poll/epoll的串口操作
转自:http://www.cnblogs.com/darryo/p/selectpollepoll-on-serial-port.html In this article, I will use t ...
随机推荐
- movzbl和movsbl
汇编语言中最最常用的指令 -- 数据传送指令,也是我们接触的第一种类别的汇编指令.其指令的格式为:“mov 源操作数, 目的操作数”.mov系列支持从最小一个字节到最大双字的访问与传送.其中movb用 ...
- nginx负载均衡 - session失效
最近迷上了Nginx,真实麻雀虽小,五脏俱全..功能实在强大.. nginx不单可以作为强大的web服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态.静态页面的分离,可以 ...
- the field is sometimes used inside synchronized block and sometimes used without synchronization
http://stackoverflow.com/questions/28715625/is-it-safe-to-use-field-inside-and-outside-synchronized- ...
- [转] android自动化之MonkeyRunner测试环境配置(一)
Android自动化测试之MonkeyRunner 一.Android自动化测试之环境搭建 1.1 Android-sdk介绍 ¢ SDK(Software development kit)软件开发 ...
- Android开发之parseSdkContent failed Could not initialize class android.graphics.Typeface
在进行android开发过程中,忽然发现经常弹出来parseSdkContent failed 这个错误,然后google了下解决办法 方法1: 删除.android文件 重启eclipse. 该方法 ...
- [原]Unity3D深入浅出 - 常用类的成员变量和成员函数(Tranform、Time、Random、Mathf、Input)
Transform的成员变量 Transform的成员函数 Time类,获取和时间相关的信息,可用来计算帧速率,调整时间流逝的速度等. Random类,可用来生成随机数,随机点和旋转. Mathf类提 ...
- android源码GIT下载
mkdir device cd device git clone https://android.googlesource.com/device/common.git mkdir htc cd htc ...
- PHP如何大幅度提升运行效率? -- 把它编译成机器码!
书接上回 今天讨论如何大幅度提升PHP的运行效率. 在这,我们不纠结神马单双引号.全局变量.OO.require_once.错误抑制.... 在这,我们也不讨论APC.opcache.XCac ...
- 【转】蓝牙4.0——Android BLE开发官方文档翻译
原文网址:http://ricardoli.com/2014/07/31/%E8%93%9D%E7%89%9940%E2%80%94%E2%80%94android-ble%E5%BC%80%E5%8 ...
- 白话spring依赖注入
Spring能有效地组织J2EE应用各层的对象.Action?Service?DAO?,都可在Spring的管理下有机地协调.运行.Spring将各层的对象以松耦合的方式组织在一起,对象与对象之间没有 ...