I/O多路转接select/poll/epoll的对比
2017-07-01 18:45
211 查看
【I/O复用模型】
〈原理〉
I/O复用是让应用程序可以同时对多个I/O端口进行监控以判断其上的操作是否可以进行,达到时间复用的目的。举例而言,如果用监控来自10根不同地方的水管(I/O端口)是否有水流到达(即是否可读),那么需要10个人(即10个线程或10处代码)来做这件事。如果利用某种技术(比如摄像头)把这10根水管的状态情况统一传达到某一点,那么就只需要1个人在那个点进行监控就行了,而类似与select或epoll这样的多路I/O复用机制就好比是摄像头的功能,它们能够把多个I/O端口的状况反馈到同一处,比如某个特定的文件描述符上,这样应用程序只需利用对应的select()、poll()或epoll()系统调用阻塞关注这一处即可。具体的select、poll、epoll模型在后面讲。
〈优点〉
相比多进程多线程服务器,由于I/O多路复用是在单一进程的上下文中的,因此每个逻辑流程都能访问该进程的全部地址空间,所以开销比多进程低得多;
〈缺点〉
因为它的开销小,必然在编程方面就会麻烦一点。
【多进程模型】
〈原理〉
构造并发最简单的就是使用多进程,像fork函数。例如,一个并发服务器,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。
〈优点〉
①每个进程互相独立,即使子进程崩溃也不影响主程序的稳定性;
②通过增加CPU就可以很容易地扩充性能;
③可以尽量减少线程加锁/解锁的影响来提高性能;
④每个子进程都有2GB地址空间和相关资源,因此总体能够达到的性能上限非常大。
〈缺点〉
①逻辑控制复杂,需要和主程序交互;
②需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算
③多进程调度开销比较大。
【多线程模型】
〈原理〉
线程和进程的执行模型有些相似,每个进程的声明周期都是一个线程,我们称之为主线程。线程是对等的,主线程跟其他线程的区别就是它先执行。
〈优点〉
①无需跨进程边界;
②程序逻辑和控制方式简单;
③所有线程可以直接共享内存和变量等;
④线程方式消耗的总资源比进程方式好;
〈缺点〉
①每个线程与主程序共用地址空间,受限于2GB地址空间;
②线程之间的同步和加锁控制比较麻烦;
③一个线程的崩溃可能影响到整个程序的稳定性;
④到达一定的线程数程度后,即使再增加CPU也无法提高性能了。
【I/O多路转接select】
〈select〉
select允许进程指示内核等待多个事件中的任何一个发送,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒。
select系统调用让程序监视多个文件句柄的状态变化。程序会停在select的地方等待,直到被监视的文件句柄有一个或多个发生了状态改变。
文件句柄实际上是一个整数,比如0是标准输入,1是标准输出,2是标准错误输出,对应的FILE* 结构的表示就是stdin、stdout、stderr。
〈select的特点〉
①select可以监控的文件描述符个数取决与sizeof(fd_set)的值;
②在将fd加入select监控集的同时,还需要一个array 来保存放到select监控集中的fd,原因是 a)用于在select返回后,array作为源数据和fd_set进行FD_ISSET判断;b)select返回后会把以前加入的但并没有事件发生的fd移除,因此每次开始select前都要重新从array取得fd并逐一加入到array中;
综上所述,select模型必须在select之前将fd加入到array中,select返回后再循环array判断是否有时间发生。
〈缺点〉
①每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;
②同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大;
③select支持的文件描述符数量小,默认是1024。
〈select服务器〉
待更新
【poll】
〈原理〉
poll使用一个 pollfd的指针实现。pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式,并且pollfd没有最大数量限制。和select函数一样,poll返 回后,需要轮询pollfd来获取就绪的描述符。
〈缺点〉
虽然pollfd没有最大数量限制,但是事实上,随着监视的描述符数量的增长,其效率也会线性下降。
〈poll服务器〉
待更新
【epoll】
〈原理〉
epoll是为处理⼤大批量句柄而作了改进的poll。epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时, 返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一 个数组中依次取得相应数量的文件描述符即可,这里使用了内存映射技术,这样便彻底省掉了这些⽂文件描述符在系统调用时复制的开销。
〈优点〉
①支持一个进程打开大数目的socket描述符。epoll没有这个限制,它所支持的FD上限是最大可以打开文件的 数目,这个数字一般远大于2048;
②IO效率不随FD数目增加而线性下降。epoll不需要像select/poll一样每次调用都会线性扫描全部的集合,
导致效率呈现线性下降。它只会对"活跃"的socket进行操作,这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的;
③使用了mmap加速内核与用户空间的消息传递。无论是select、poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。
〈epoll服务器〉
待更新
〈原理〉
I/O复用是让应用程序可以同时对多个I/O端口进行监控以判断其上的操作是否可以进行,达到时间复用的目的。举例而言,如果用监控来自10根不同地方的水管(I/O端口)是否有水流到达(即是否可读),那么需要10个人(即10个线程或10处代码)来做这件事。如果利用某种技术(比如摄像头)把这10根水管的状态情况统一传达到某一点,那么就只需要1个人在那个点进行监控就行了,而类似与select或epoll这样的多路I/O复用机制就好比是摄像头的功能,它们能够把多个I/O端口的状况反馈到同一处,比如某个特定的文件描述符上,这样应用程序只需利用对应的select()、poll()或epoll()系统调用阻塞关注这一处即可。具体的select、poll、epoll模型在后面讲。
〈优点〉
相比多进程多线程服务器,由于I/O多路复用是在单一进程的上下文中的,因此每个逻辑流程都能访问该进程的全部地址空间,所以开销比多进程低得多;
〈缺点〉
因为它的开销小,必然在编程方面就会麻烦一点。
【多进程模型】
〈原理〉
构造并发最简单的就是使用多进程,像fork函数。例如,一个并发服务器,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。
〈优点〉
①每个进程互相独立,即使子进程崩溃也不影响主程序的稳定性;
②通过增加CPU就可以很容易地扩充性能;
③可以尽量减少线程加锁/解锁的影响来提高性能;
④每个子进程都有2GB地址空间和相关资源,因此总体能够达到的性能上限非常大。
〈缺点〉
①逻辑控制复杂,需要和主程序交互;
②需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算
③多进程调度开销比较大。
【多线程模型】
〈原理〉
线程和进程的执行模型有些相似,每个进程的声明周期都是一个线程,我们称之为主线程。线程是对等的,主线程跟其他线程的区别就是它先执行。
〈优点〉
①无需跨进程边界;
②程序逻辑和控制方式简单;
③所有线程可以直接共享内存和变量等;
④线程方式消耗的总资源比进程方式好;
〈缺点〉
①每个线程与主程序共用地址空间,受限于2GB地址空间;
②线程之间的同步和加锁控制比较麻烦;
③一个线程的崩溃可能影响到整个程序的稳定性;
④到达一定的线程数程度后,即使再增加CPU也无法提高性能了。
【I/O多路转接select】
〈select〉
select允许进程指示内核等待多个事件中的任何一个发送,并只在有一个或多个事件发生或经历一段指定的时间后才唤醒。
select系统调用让程序监视多个文件句柄的状态变化。程序会停在select的地方等待,直到被监视的文件句柄有一个或多个发生了状态改变。
文件句柄实际上是一个整数,比如0是标准输入,1是标准输出,2是标准错误输出,对应的FILE* 结构的表示就是stdin、stdout、stderr。
〈select的特点〉
①select可以监控的文件描述符个数取决与sizeof(fd_set)的值;
②在将fd加入select监控集的同时,还需要一个array 来保存放到select监控集中的fd,原因是 a)用于在select返回后,array作为源数据和fd_set进行FD_ISSET判断;b)select返回后会把以前加入的但并没有事件发生的fd移除,因此每次开始select前都要重新从array取得fd并逐一加入到array中;
综上所述,select模型必须在select之前将fd加入到array中,select返回后再循环array判断是否有时间发生。
〈缺点〉
①每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;
②同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大;
③select支持的文件描述符数量小,默认是1024。
〈select服务器〉
待更新
【poll】
〈原理〉
poll使用一个 pollfd的指针实现。pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式,并且pollfd没有最大数量限制。和select函数一样,poll返 回后,需要轮询pollfd来获取就绪的描述符。
〈缺点〉
虽然pollfd没有最大数量限制,但是事实上,随着监视的描述符数量的增长,其效率也会线性下降。
〈poll服务器〉
待更新
【epoll】
〈原理〉
epoll是为处理⼤大批量句柄而作了改进的poll。epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时, 返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一 个数组中依次取得相应数量的文件描述符即可,这里使用了内存映射技术,这样便彻底省掉了这些⽂文件描述符在系统调用时复制的开销。
〈优点〉
①支持一个进程打开大数目的socket描述符。epoll没有这个限制,它所支持的FD上限是最大可以打开文件的 数目,这个数字一般远大于2048;
②IO效率不随FD数目增加而线性下降。epoll不需要像select/poll一样每次调用都会线性扫描全部的集合,
导致效率呈现线性下降。它只会对"活跃"的socket进行操作,这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的;
③使用了mmap加速内核与用户空间的消息传递。无论是select、poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。
〈epoll服务器〉
待更新
相关文章推荐
- I/O 多路复用之select、poll、epoll实现原理及对比总结
- 高级I/O多路转接之select poll epoll 区别
- 【Nginx】I/O多路转接之select、poll、epoll
- 多路复用 I/O 多路转接 select / poll / epoll
- I/O多路转接之select、poll、epoll
- I/O多路转接之select、poll、epoll
- 基于表格形式的select,poll,epoll对比-IO多路复用函数的应用场景
- 高性能服务器——I/O多路转接的三种模式(select &poll& epoll)
- I/O多路转接复用机制---select,poll,epoll
- Linux/Unix select函数 及select/poll与epoll的对比
- I/O多路复用之select,poll,epoll简介
- select、poll、epoll区别对比
- epoll 的实现原理以及与poll,select 的对比
- select/poll/epoll对比分析
- IO多路转接之select、poll、epoll
- 多路转接之poll和select
- Linux下多路复用IO接口 epoll select poll 的区别
- UNIX环境高级编程——I/O多路转接(select、pselect和poll)
- Linux I/O多路复用之select,poll与epoll区别
- IO多路复用--select、 poll、 epoll的区别