三者都是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学习的更多相关文章

  1. Java IO 学习(二)select/poll/epoll

    如上文所说,select/poll/epoll本质上都是同步阻塞的,但是由于实现了IO多路复用,在处理聊天室这种需要处理大量长连接但是每个连接上数据事件较少的场景时,相比最原始的为每个连接新开一个线程 ...

  2. 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!

    系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...

  3. select/poll/epoll on serial port

    In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port t ...

  4. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

  5. 多进程、协程、事件驱动及select poll epoll

    目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...

  6. Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO

    本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO   1.  多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...

  7. select poll epoll三者之间的比较

    一.概述 说到Linux下的IO复用,系统提供了三个系统调用,分别是select poll epoll.那么这三者之间有什么不同呢,什么时候使用三个之间的其中一个呢? 下面,我将从系统调用原型来分析其 ...

  8. 转--select/poll/epoll到底是什么一回事

    面试题:说说select/poll/epoll的区别. 这是面试后台开发时的高频面试题,属于网络编程和IO那一块的知识.Android里面的Handler消息处理机制的底层实现就用到了epoll. 为 ...

  9. IO多路复用select/poll/epoll详解以及在Python中的应用

    IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...

  10. [serial]基于select/poll/epoll的串口操作

    转自:http://www.cnblogs.com/darryo/p/selectpollepoll-on-serial-port.html In this article, I will use t ...

随机推荐

  1. STM32硬件复位时间

    两个参数,,1低电平时间 2低电平压值 1.stm32复位时间 ------  低电平时间:1.5 至 4.5 ms   2.压值

  2. Android 签名(6)编译时源码的签名

    1,使用源码中的默认签名 在源码中编译一般都使用默认签名的,在某源码目录中用运行下面命令能看到签名命令. $ mm showcommands Android提供了签名的程序signapk.jar,用法 ...

  3. 新版本的tlplayer for android ,TigerLeapMC for windows发布了

    tlplayer for android 新版本修正了图像倾斜等等问题,增加了动态水印功能. 支持hls(m3u8),http,rtsp,mms,rtmp等网络协议. 声明tlplayer 上的变速不 ...

  4. WPF中映射clr namspace

    1. xaml中直接映射为prefix xmlns:prefix="clr-namespace:MyApplication.Modules.Entity;assembly=MyAssembl ...

  5. openSession()和getCureentSession()的区别

    openSession():永远是打开一个新的session getCureentSession():如果当前环境有session,则取得原来已经存在的session,如果没有,则创建一个新的sess ...

  6. 通过移动的Mas接口发送短信

    1. 首先,需要移动公司提供的用户名.密码.服务ID.接口Url等信息. 2. 将短信信息整理成XML格式的字符串,再转为byte数组,通过POST的方式,将短信发往Mas接口.需要引用"M ...

  7. .NET 4.0中的泛型协变和逆变

    随Visual Studio 2010 CTP亮相的C#4和VB10,虽然在支持语言新特性方面走了相当不一样的两条路:C#着重增加后期绑定和与动态语言相容的若干特性,VB10着重简化语言和提高抽象能力 ...

  8. JavaScript基础大全篇

    本章内容: 简介 定义 注释 引入文件 变量 运算符 算术运算符 比较运算符 逻辑运算符 数据类型 数字 字符串 布尔类型 数组 Math 语句 条件语句(if.switch) 循环语句(for.fo ...

  9. 使用appium做安卓手机web自动化测试 真机demo

    一:appium相关环境搭建过程略. 二:连接真机: 1.手机(andriod 4.2.2)连接电脑,打开USB调试模式. 2.运行cmd 输入 adb devices -l 查看UDID,如图: 3 ...

  10. Gdb 常用命令

    命令名称 含义 示例 b  fun_name 设置断点 b  main b 行号 if  条件 设置带条件断点 如:b 11 if  i==10 n 下一行 n s 跳入函数内部 s  sum fin ...