什么是IO?什么是多路?
IO: 在操作系统中,数据在内核态和用户态之间的读写操作。
大部分情况下指的是网络IO。
多路: 大部分情况下指多个TCP连接(多个Socket或者多个Channel)
什么是IO多路复用?
一种同步的IO模型,可以实现一个线程监视多个文件句柄。
一但某个文件句柄就绪,就能够通知到对应的应用程序进行相应的读写操作。
没有文件句柄就绪时就会阻塞应用程序,从而释放cpu资源。
简单点说:一个或者多个线程处理多个TCP连接,尽可能的减少系统的开销,而无需创建和维护过多的进程或线程。
IO多路复用模型
select模型
基本原理: 采用轮询加遍历的方式。
在客户端操作服务器时,会创建3种文件描述符(写描述符、读描述符、异常描述符)。select会阻塞监视这三种文件描述符,等到有数据可读、可写或者出异常时,都会返回。返回后通过遍历fdset来找到就绪的fd,然后去触发相应的IO操作
优点: 跨平台支持性好,几乎在所有的平台上支持
缺点: 随着FD数量的增加,性能下降。每次调用select方法的时候都需要把FD集合从用户态拷贝到内核态,并进行遍历。
OS对单个进程打开的FD数量是有限的,一般默认是1024个。虽然能够通过操作系统的宏定义FD_SETSIZE来修改FD数量的限制,但是再IO吞吐量巨大的情况下,效率提升仍然有限
#######缺点总结######
1.采用线性遍历的方式获取可用的fd文件描述符
2.可维护文件描述符大小有限制为1024
poll模型
基本原理: 采用轮询加遍历的方式。
poll模型采用的是链表方式来存储FD。
优点: 没有最大的fd数量限制
缺点: 同select。采用轮询方式来进行全盘扫描,随着fd数量增多而导致性能下降
epoll模型
基本原理: 采用时间通知机制来触发相关IO操作的。
没有fd个数的限制,而且从用户态拷贝到内核态只需要一次。因为主要是通过调用系统底层的函数实现注册、激活fd,大大提高了性能
调用函数
epoll_create()函数:在系统启动的时候,会在linux内核里面去申请一个B+树结构的文件系统,然后在返回epoll对象(fd对象)
epoll_ctl()函数:它会在每新建一个连接的时候,会同步更新epoll对象中的FD,并且会绑定一个callback回调函数。
epoll_wait()函数:它会轮询所有的callback集合,并且去触发对应的IO操作。
优点: 将轮询改成了回调,大大提高了CPU的执行效率;
没有fd数量的限制,也不会随着fd数量的增加而导致效率下降;
能支持的fd上限是os的最大文件句柄数(一般1G内存能支持10w个句柄),在分布式系统中常用的组件是redis、nginx
缺点: 只能在Linux下工作
#######优点总结######
1.每当fd就绪,系统采用回调函数将fd放入就绪列表,效率非常高。
2.最大连接数没有限制