码迷,mamicode.com
首页 > 其他好文 > 详细

多路复用之select、epoll、poll

时间:2016-06-03 23:09:33      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:服务器   多线程   程序   接口   空间   

IO的多路复用:一个进程可以监视多个描述符,一旦某个描述符读就绪或写就绪,能够通知进程程序进行相应的读写操作

使用场景:

1.当客户处理多个描述符(网络套接口)或一个客户同时处理多个套接口

2.TCP服务器既要处理监听套接口又要处理已经连接的套接口

3.一个服务器处理多个服务或多个协议也要使用I/O复用

与多进程和多线程相比,I/O多路复用最大优点系统开销小,系统也不必创建进程或线程,因而也不用维护这些进程和线程

支持I/O多路复用的系统调用:select、poll、epoll本质上都是同步IO,因此它们都要在读写事件就绪后自己负责读写

1.select

基本原理:该函数监视的文件描述符分读描述符集、写描述符集、异常描述符集,调用该函数后select就会一直阻塞等待,直到有描述符就绪(至少有一个),或者超时等待

优点:具有良好的跨平台性

缺点:

1.单个进程所打开文件描述符个数有数量限制,32位平台下默认1024,64位平台下默认2048

2.每次都要对sock集进行线性扫描(轮询)每次都要从用户态切换到内核态,需要的开销大

3.需要维护一个用来存放大量描述符的数据结构(数组),在内核和用户空间之间的传递复制开销也很大

4.每次调用select函数前都要对timeout进行初始化,还要对它所关心的文件描述符所在的描述符集进行初始化工作

select中的timeout结构体:

1.若传NULL,就是将select设置为阻塞状态,一定要等到一个或多个描述符状态发生变化

2.若设为0秒0毫秒,则变为一个非阻塞函数,不管描述符状态是否发生变化都立即返回

3.若设为大于0,则函数会在timeout时间内阻塞,超时时间内若有事件到来就返回

2.poll

基本原理:将用户传入的数组拷贝到内核区,轮询查看每个描述符对应的事件状态,若事件就绪就加入等待队列中继续遍历,若遍历结束没有事件就绪,就挂起进程,直到有就绪事件到达或超时被唤醒,之后又要轮询

poll中含有一个结构体,它包含了要监视的事件和发生的事件,不在使用select中的参数值传递方式。

优点:没有最大连接数的限制,因为它基于链表来存储

水平触发,在每次调用该函数时都会再次检测该socket来查看该socket缓冲区中的数据是否已被读完

缺点:

1.在每次调用该函数后都要轮询遍历描述符来获取就绪的socket

2.当同时连接大量客户端时,而在某一时刻可能只有很少的处于就绪状态,随着监视的描述符数量增长,它的效率也会降低

适用场景:连接数量少并且每个连接都十分活跃

3.epoll:使用一个描述符来管理多个描述符,将用户所关心的描述符相应事件存放到内核的事件表上,只需拷贝一次

使用三个函数:

epoll_create创建一个epollfd

epoll_ctl进行注册某个socket描述符

epoll_wait等待就绪事件

基本原理:支持水平触发和边缘触发,一般默认水平触发,当使用边缘触发时,只告诉进程哪些描述符已经变为就绪状态并且只通知一次。会先注册所要关心的文件描述符及它所关心的事件,内核也会采用相应的回调机制来激活该描述符,使用epoll_wait只返回就绪的事件

优点:

1.没有最大并发连接的限制,不需要轮询的方式每次都要遍历描述符集,不会随着描述符数目的增加而下降

2.使用mmap(内存映射技术)加速与内核之间的消息传递,减少了从用户到内存的拷贝次数

,不同于select和poll的消息传递方式,通过内核与用户空间共享一块内存来实现

两种工作模式:

LT:当调用epoo_wait检测到描述符事件发生并通知应用程序,应用程序应立即处理,若不处理,则下次还会再次告知上层应用程序

ET:调用epoll_wait检测到描述符事件发生并通知上层应用且只通知一次,只支持非阻塞socket(避免由于一个句柄的阻塞读或写让后续的多个文件描述符一直阻塞等待),在很大程度上减少了时间被重复触发的次数

适用场景:同时处理大量客户端同时请求连接服务器



多路复用之select、epoll、poll

标签:服务器   多线程   程序   接口   空间   

原文地址:http://10541559.blog.51cto.com/10531559/1785984

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!