IO多路复用技术select、poll、Epoll讲解

什么是IO多路复用:

I/O多路复用,I/O是指网络I/O,多路指多个TCP连接(即socket或者channel),复用是指复用一个或几个线程。

简单来说:就是使用一个或者几个线程处理多个TCP连接
最大优势是减少系统开销,不必创建过多的进程/线程,也不必维护这些进程/线程

select:

基本原理

监视文件3类描述符:writefds、readfds、和exceptfds,调用后select函数会阻塞住,等有数据 可度、可写、出异常或者超时就会返回,select函数正常返回后,通过遍历fdset整个数据才能发现哪些句柄发生了事件,来找到就绪的描述符fd,然后进行对应的IO操作,几乎在所有的平台上支持,跨平台支持性好

几乎在所有平台上支持,跨平台支持性好

缺点

1)select采用轮询的方式扫描文件描述符,全部扫描,随着文件描述符fd数量增多而性能下降

2)每次调用select(),需要把fd集合从用户态拷贝到内核态,并进行遍历(消息传递都是从内核到用户空间)

3)最大的缺陷就是单个进程打开的fd有限制,默认1024(可修改宏定义,但是效率仍然慢)

static final int MAX_FD = 1024

poll

基本原理

select()和poll()系统调用的大体一样,处理多个描述符也是使用轮询的方式,根据描述符的状态进行处理,一样需要把fd集合从用户态拷贝到内核态,并进行遍历。最大的区别是:poll没有最大文件描述符限制(使用链表的方式存储fd)

epoll

基本原理

在Nginx用的很多。在2.6内核中提出的,对比select和poll,epoll更加灵活,没有描述符限制,用户态拷贝到内核态只需要一次
使用事件通知,通过epoll_ctl注册fd,一但该fd就绪,内核就会采用callback的回调机制来激活对应的fd

优点

1)没fd这个限制,所支持的fd上线是操作系统的最大文件句柄数,1G内存大概支持10万个句柄。所以说16G内存就能支持百万连接

2)效率提高,使用回调通知而不是轮询的方式,不会随着FD数目的增加效率下降

3)通过callback机制通知,内核和用户空间mmap同一块内存实现

Linux内核核心函数

1)epoll_create()在Linux内核里面申请一个文件系统B+数,返回epoll对象,也是一个fd

2)epoll_ctl()操作epoll对象,在这个对象里面修改添加删除对应的链接fd,绑定一个callback函数

3)epoll_wait()判断并完成对应的IO操作

缺点

编程模型比select/poll复杂

例子:100万个链接,里面有1万个链接是活跃,在select、poll、epoll分别是怎样的表现?

select:不修改宏定义,则需要1000个进程才可以支持100万链接

poll:100万个链接,遍历都响应不过来了,还有空间的拷贝消耗大量的资源

epoll:不用去遍历fd,通过三个函数,第一个函数去注册,第二个去操作epoll对象,并绑定回调函数,第三个函数判断完成对应的IO操作

猜你喜欢

转载自blog.csdn.net/q736317048/article/details/113747523