Linux中的IO复用接口简介(文件监视?)
I/O复用是Linux中的I/O模型之一。所谓I/O复用,指的是进程预先告诉内核,使得内核一旦发现进程指定的一个或多个I/O条件就绪,就通知进程进行处理,从而不会在单个I/O上导致阻塞。
在Linux中,提供了select、poll、epoll三类接口来实现I/O复用。
select函数接口
select中主要就是一个select函数,用于监听指定事件的发生,原型如下:
1 |
#include<sys/select.h> |
其中各参数的含义如下:
maxfd:最大文件描述符加1,比它小的从0开始的描述符都将被监视,它的值不能超过系统中定义的FD_SETSIZE(通常是1024)。
rset,wset,eset:分别表示监视的读、写、错误的描述符位数组,通常是一个整数数组,每一个整数可以表示32个描述符是否被监视。需要注意的是这几个参数都是值-结果参数,在调用select后这几个参数将表示哪些描述符就绪了。通过以下几个宏可以很方便的操作fset数组:
1 |
void FD_ZERO(fd_set *fdset); |
timeout:超时时间,即select最长等待多久就返回,为NULL时表示等到有操作符准备就绪后才返回。该时间可以精确到微秒,其结构如下:
1 |
struct timeval{ |
描述符就绪条件
对于普通数据的读写,描述符就绪显而易见,但仍有一些特殊情况时描述符会读写就绪,UNP中对描述符的读写就绪条件进行了说明。1)满足以下4个条件时,描述符准备好读
a)套接字接收缓冲区中的数据字节数大于套接字接收缓冲区低水位标记的当前大小(默认为1),读将会返回大于0的数。
b)该连接的读半部关闭,读将会返回0。
c)套接字上有一个错误待处理,读将返回-1。
d)该套接字是一个监听套接字并且已完成连接数不为0。2)满足以下4个条件时,描述符准备好写
a)套接字发送缓冲区中的可用空间字节数大于等于套接字发送缓冲区低水位标记的当前大小(默认2048),写将会返回大于0的数。
b)该连接的写半部关闭,写将会返回EPIPE。
c)套接字上有一个错误待处理,写将返回-1。
d)使用非阻塞式connect的套接字建立有结果返回。
poll函数接口
poll中的主要函数也只有一个poll,与select作用类似,但参数有所不同,函数原型如下:
1 |
#include<poll.h> |
其中各参数的含义如下:
fdarray:是一个指向pollfd结构数组的指针,维护着描述符以及事件信息,该结构体是poll里比较核心的结构体,结构如下:
1 |
struct pollfd{ |
该结构体通过两个变量区分关注的事件和发生的事件,从而避免了使用值-结果参数。events和revents可选的标志位如下:
1 |
POLLIN //普通或优先级带数据可读 |
nfds:指定结构体数组中元素的个数。
timeout:每次调用poll最大等待的毫秒数,负值代表等待到直到有事件触发。
epoll函数接口
epoll主要有三个函数,函数原型如下:
1 |
#include <sys/epoll.h> |
epoll_create(int size)
size:能监听多少个描述符,返回一个epoll描述符。注意使用完epoll后要关闭该描述符。
epoll_ctl(int efd, int op, int fd, struct epoll_event *event)
efd:epoll_create返回的epoll描述符
op:表示动作,可以在以下三个宏里选择一个
1 |
EPOLL_CTL_ADD //注册新的fd到epoll中 |
fd:要监听的fd
event:告诉内核要监听什么事件,其结构如下:
1 |
typedef union epoll_data { |
其中events表示epoll事件,可选的标志位如下:
1 |
EPOLLIN //描述符可以读 |
而epoll_data_t使用了union来存储数据,用户可以使用data来存放一些关于该fd的额外内容。
标志位中比较特殊的是EPOLLET这个选项,这个选项将EPOLL设置为边缘触发模式,EPOLL有EPOLLET和EPOLLLT两种工作模式。
EPOLLLT(Level Triggered,水平触发模式):默认工作模式,支持block和no-block socket,内核通知你描述符事件后,如果不进行操作,会一直通知。
EPOLLET(Edge Triggered,边缘触发模式):高速工作模式,只支持no-block socket,只会在描述符状态由未就绪转为就绪时会通知一次,使用该模式时,如果程序编写的不够健全,是很容易出现问题的。
epoll_wait(int efd, struct epoll_event *events, int maxevents, int timeout);
该函数与select和poll函数的功能类似,监视指定事件的发生并返回给用户。
efd:epoll_create返回的opoll描述符。
events:用来从内核得到事件的集合。
maxevents:用来告知内核events数组的大小。
timeout:超时时间,-1将阻塞直到有事件发生,否则表示最多等待多少毫秒后函数就返回。
select,poll,epoll比较
select
- select能监控的描述符个数由内核中的FD_SETSIZE限制,仅为1024,这也是select最大的缺点,因为现在的服务器并发量远远不止1024。即使能重新编译内核改变FD_SETSIZE的值,但这并不能提高select的性能。
- 每次调用select都会线性扫描所有描述符的状态,在select结束后,用户也要线性扫描fd_set数组才知道哪些描述符准备就绪,等于说每次调用复杂度都是O(n)的,在并发量大的情况下,每次扫描都是相当耗时的,很有可能有未处理的连接等待超时。
- 每次调用select都要在用户空间和内核空间里进行内存复制fd描述符等信息。
poll
- poll使用pollfd结构来存储fd,突破了select中描述符数目的限制。
- 与select的后两点类似,poll仍然需要将pollfd数组拷贝到内核空间,之后依次扫描fd的状态,整体复杂度依然是O(n)的,在并发量大的情况下服务器性能会快速下降。
epoll
- epoll维护的描述符数目不受到限制,而且性能不会随着描述符数目的增加而下降。
- 服务器的特点是经常维护着大量连接,但其中某一时刻读写的操作符数量却不多。epoll先通过epoll_ctl注册一个描述符到内核中,并一直维护着而不像poll每次操作都将所有要监控的描述符传递给内核;在描述符读写就绪时,通过回掉函数将自己加入就绪队列中,之后epoll_wait返回该就绪队列。也就是说,epoll基本不做无用的操作,时间复杂度仅与活跃的客户端数有关,而不会随着描述符数目的增加而下降。
- epoll在传递内核与用户空间的消息时使用了内存共享,而不是内存拷贝,这也使得epoll的效率比poll和select更高。
程序示例
分别使用select,poll和epoll实现了简单的回显服务器程序,客户端使用select来实现。其中select和poll程序主要参考unp的实现,只是Demo程序,对一些异常情况没有进行处理。
客户端程序
使用select来监听终端输入和连接服务器的流输入,这样可以保证客户端不在某一个输入流上死等。
1 |
#include <sys/socket.h> |
select服务器
1 |
#include <sys/socket.h> |
poll服务器
1 |
#include <sys/socket.h> |
epoll服务器
回显服务器使用了ET高速模式。在该模式下,最好所有的操作都是非阻塞的,程序中套接字都设置为了non-socket,并且使用了缓冲区,在读到数据时先将数据存到缓冲区中,下次可写时才将数据从缓冲区写回客户端。
另外,在ET模式下,accept、read、write时都要使用循环直到读到EAGAIN才能说明没有数据了。
1 |
#include <sys/epoll.h> |
本文标题:Linux中的IO复用接口简介
文章作者:Vimer Su
发布时间:2013年11月19日 - 19时56分
最后更新:2016年06月04日 - 22时57分
原始链接:http://vimersu.win/blog/2013/11/19/linux-io-reuse-interface/
许可协议: "署名-非商用-相同方式共享 3.0" 转载请保留原文链接及作者。
Linux中的IO复用接口简介(文件监视?)的更多相关文章
- Linux网络编程-IO复用技术
IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...
- LINUX网络编程 IO 复用
参考<linux高性能服务器编程> LINUX下处理多个连接时候,仅仅使用多线程和原始socket函数,效率十分低下 于是就出现了selelct poll epoll等IO复用函数. 这 ...
- Linux基础(06)IO复用
在Windows文件指的就是普通的肉眼可见的文件 , 而Linux一切皆文件 https://blog.csdn.net/nan_nan_nan_nan_nan/article/details/812 ...
- 深入理解JAVA I/O系列六:Linux中的IO模型
IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大致描述了数据从外部磁盘向运行中程序的内存中移动的过程. 用户空间.内核空间 现在操作系统都是采用虚拟存储器, ...
- 深入理解JAVA I/O系列六:Linux中的IO模型(转载的文章非常值得学习)
From:http://www.cnblogs.com/dongguacai/p/5770287.html IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大 ...
- linux中的 IO端口映射和IO内存映射
参考自:http://blog.csdn.net/zyhorse2010/article/details/6590488 CPU地址空间 (一)地址的概念 1)物理地址:CPU地址总线传来的地址,由硬 ...
- imx6中iomux IO复用
IOMUX Controller (IOMUXC) IO多路复用控制器1.overviewThe IOMUX Controller (IOMUXC), together with the IOMUX, ...
- linux中/etc/passwd和/etc/shadow文件说明
/etc/passwd是用来存储登陆用户信息: [root@localhost test]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x ...
- 如何在Linux中使用rz/sz工具进行文件传输
在Linux中,使用rz/sz工具能够进行Linux和windows之间的文件传输,那么要如何使用rz/sz工具工具呢?下面小编就给大家介绍下Linux下如何使用rz/sz工具进行文件传输,一起来学习 ...
随机推荐
- JAVA 鲜为人知的二次标记 第六节
又到周末啦,祝各位小伙伴有个愉快的周末.同时也不要忘了学习,上班的同伴们可以利用这两天的时间好好提升自己,在读书的小伙伴们也可以慢慢整理这一周所学到的东西.很多情况下我们看到对自己有用的东西都会保存起 ...
- Spark 算子
0.parallelize 1.map 2.mapValues 3.flatMap 4.mapPartitions 5.mapPartitionsWithIndex 6.filter 7.reduce ...
- MySQL AUTO_INCREMENT 简介
可使用复合索引在同一个数据表里创建多个相互独立的自增序列,具体做法是这样的:为数据表创建一个由多个数据列组成的PRIMARY KEY OR UNIQUE索引,并把AUTO_INCREMENT数据列包括 ...
- cocos2d-x -------之笔记篇 动画的实现
cocos2d-x 动画的实现 一.实现原理 动画的实现其实就是使用一个完整的动作图片集来实现动画,达到动态的效果 动画动作类(CCAnimate)是加载一个动画类来实现动作. 动画类(CCAnima ...
- 3D项目处理点选操作步骤
1.用notepad++模型的obj格式文件,查找到模型各个部分的名称,命名规则:g mesh......,把名字改为规则命名. 2.选择处理 #ifdef _DEBUG #pragma comm ...
- [原]基于CAS实现单点登录(SSO):登录成功后,cas client如何返回更多用户信息
从cas server登录成功后,默认只能从casclient得到用户名.但程序中也可能遇到需要得到更多如姓名,手机号,email等更多用户信息的情况. cas client拿到用户名后再到数据库中查 ...
- 轻奢请向历史SAY NO_重青网_重庆青年报_重庆青年报电子版_重庆青年报网站_重庆青年报官方网站
轻奢请向历史SAY NO_重青网_重庆青年报_重庆青年报电子版_重庆青年报网站_重庆青年报官方网站 轻奢请向历史SAY NO 经济学家George Taylor在他著名的"裙摆指数" ...
- 7.15 css与js 选择奇偶子元素的区别
js: 选取偶数位置的 <tr> 元素 $("tr:even") 选取奇数位置的 <tr> 元素 $("tr:odd") css 选取偶 ...
- JQuery打造下拉框联动效果
做联动效果,若是用纯JavaScript来做,往往须要辅助页面保存须要刷新的结果集,然后渲染到原页面.考虑将须要动态刷新的内容自己主动拼接到前一个下拉框之后,当前一个下拉框onchange后,同级的后 ...
- Choosing Between ElasticSearch, MongoDB & Hadoop
An interesting trend has been developing in the IT landscape over the past few years. Many new tech ...