2016.8.25--I/O复用函数(select,poll,epoll)
来源:互联网 发布:x8软件下载 编辑:程序博客网 时间:2024/05/05 22:24
I/O复用
IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合:
(1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。
(2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。
(3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。
(4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。
(5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。
3个I/O复用函数
int select(int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);//返回值 就绪描述符的数目,超时返回0,出错返回-1//第一个参数nfds 指定待测试的描述字的个数,值是待测试的最大描述字+1//中间三个参数(readset,writeset,exceptset)指定让内核测试read,write,except的描述字,可以通过4个宏设置/* void FD_ZERO(fd_set *fdset); //清空集合 void FD_SET (int fd,fd_set *fdset); //将一个给定的文件描述符加入集合中 void FD_CLR (int fd,fd_set *fdset); //将一个给定的文件描述符从集合中删除 int FD_ISSET(int fd,fd_set *fdset); //检查集合中指定的文件描述符是否可以读写*///最后一个参数tiemout 告知内核等待所指定描述字中的任何一个就绪可以花费的时间。/* timeval结构用于指定这段时间的秒数和微秒数。 struct timeval { long tv_sec; //秒 long tv_usec; //微妙 }; 这个参数有三种可能: (1)永远等待下去:仅在有一个描述字准备好I/O时才返回。为此,把该参数设置为空指针。 (2)等待一段固定时间:在有一个描述字准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。 (3)根本不等待:检查描述字后立即返回,这称为轮询。为此,该参数必须指向一个timeval结构,而且其中的定时器值必须为0。*/
poll
int poll(struct pollfd *fds,unsigned int nfds, int timeout);/* struct pollfd { int fd; //文件描述符 short events; //等待的事件 short revents; //实际发生了的事件 };*///nfds_t类型的参数,用于标记数组fds中的结构体元素的总数量//timeout参数指定等待的毫秒数,无论I/O是否准备好,poll都会返回。 //timeout指定为负数值表示无限超时,使poll()一直挂起直到一个指定事件发生 //timeout为0指示poll调用立即返回并列出准备好I/O的文件描述符,但并不等待其它的事件。这种情况下,poll()就像它的名字那样,一旦选举出来,立即返回。//每个结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域/*POLLIN 有数据可读。POLLRDNORM 有普通数据可读。POLLRDBAND 有优先数据可读。POLLPRI 有紧迫数据可读。POLLOUT 写数据不会导致阻塞。POLLWRNORM 写普通数据不会导致阻塞。POLLWRBAND 写优先数据不会导致阻塞。POLLMSGSIGPOLL 消息可用。*/
epoll
//使用一个文件描述符管理多个描述符,将用户关心的事件存放在内核的一个事件表中,只需要copy一次(用户空间<->内核空间)int epoll_create(int size);//创建一个epolll对象//size是最大fd监听+1int epoll_ctl(int epfd ,int op ,int fd ,struct epoll_event *event);//op的取值有:EPOLL_CTL_ADD、EPOLL_CTL_MOD、EPOLL_CTL_DEL,表示你要从监听集中添加、去除或修改某个文件描述符。int epoll_wait(int epfd ,struct epoll_event *events ,int maxevent);//成功返回就绪的文件描述符的个数,失败-1,并设置errno//等待 I/O 事件的发生//epfd: 由 epoll_create() 生成的 Epoll 专用的文件描述符//epoll_event: 用于回传代处理事件的数组//maxevents: 每次能处理的事件数//timeout: 等待 I/O 事件发生的超时值 返回发生事件数。//epoll数据结构/*struct epoll_event { __uint32_t events; // Epoll events epoll_data_t data; // User data variable }; typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; *///工作方式 LT:会重复通告,直到被处理// ET:必须立即处理,不会重复通告
3个函数特点
//select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替//poll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程//select/*一个进程可监视的fd数量被限制,最大是FD_SIZE,默认是1024需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大对socket进行扫描时是线性扫描*///poll/*poll优点1)poll() 在应付大数目的文件描述符的时候相比于select速度更快 2)它没有最大连接数的限制,原因是它是基于链表来存储的。poll缺点1)大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。 2)与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符*///epoll/*epoll优点1)支持一个进程打开大数目的socket描述符(FD)2)IO效率不随FD数目增加而线性下降3)使用mmap加速内核与用户空间的消息传递。*/
关于epoll不一定比select高效的场景
并发量低,socket都比较活跃的情况下,两者效率近似
个人理解
select对每个感兴趣的事件,每次调用时都需要把FD集合从用户态拷贝到内核态
poll和select很相似,只是一个是struct pollfd,另一个是fd_set
epoll是在每次增加fd的时候,在epoll_ctl()就将fd拷贝进内核,减少了很多重复拷贝,保证每个fd只会被拷贝1次
epoll使用了callback(回调函数)机制,效率远高于轮询,所以提升了性能
推荐阅读
http://blog.csdn.net/lizhiguo0532/article/details/6568964#comments
http://blog.csdn.net/lizhiguo0532/article/details/6568968
http://blog.csdn.net/lizhiguo0532/article/details/6568969
http://m.blog.csdn.net/article/details?id=52226501 (!!!有面试需要的可以看这篇)
http://www.cnblogs.com/Anker/p/3265058.html (!!!这篇很不错)
http://blog.csdn.net/turkeyzhou/article/details/8504554
- 2016.8.25--I/O复用函数(select,poll,epoll)
- I/O复用之select、poll、epoll函数
- I/O复用中的 select poll 和 epoll
- 【整理】I/O复用模型中的 select、poll、epoll
- I/O复用实现方式:select、poll、epoll
- I/O复用的系统调用select、poll、epoll
- I/O复用之select、poll和epoll复用函数的比较
- select、poll以及epoll三组I/O复用函数的区别
- 浅谈I/O复用:select、poll、epoll
- 浅析I/O多路复用:select、poll、epoll
- I/O复用三大模型select/poll/epoll
- I/O复用 select poll epoll
- I/O多路复用---select、poll、epoll
- I/O多路复用之select/poll/epoll
- I/O多路复用(select、poll、epoll)
- Linux I/O复用:select ,poll,epoll
- 网络I/O模型select/poll/epoll
- I/O多路复用:select poll epoll
- 为人处事
- 使用Spark、Ansj分词进行词频统计
- 完美解决Mysql的Access denied for user 'root'@'%'问题
- 理财技术
- Unique Binary Search Trees
- 2016.8.25--I/O复用函数(select,poll,epoll)
- maven package skip test
- 代码注释规则
- spark自带的PageView测试用例
- 电子产品设计管控
- TListView加入进度条
- 怎么让EditText上来就显示出键盘?
- Android Retrofit 实现文字(参数)和多张图片一起上传
- 安卓谷歌电子市场学习笔记系列——PagerTabStrip