1、IO多路复用
多路是指?多个业务方(句柄)并发下来的 IO 。复用是指?复用这一个后台处理程序。Loop程序循环。 一对多,一个loop处理多个fd.
VS多线程:多线程有瓶颈,线程数过多,性能反而差。
实现方式 select 时间复杂度O(n) 有I/O发生了,不知道对应的流,只能无差别轮询,找出能读的数据,或者写入的数据,设置或检查存放fd标志位的数据结构来进行下一步处理,缺点单个进程监视的fd数量有限, 32位默认监听1024个 64位监听2048个
poll 时间复杂度O(n) 本质和select没区别,将用户传入的数组拷贝到内核空间,然后查询fd对应的设备状态,但是没有最大连接数控制,基于链表存储
epoll 时间复杂度O(1) event poll 同于忙轮询和无差别轮询,epoll会把哪个流对应的I/O事件通知,每个事件关联fd 事件驱动
以 select 和 epoll 来对比举例,池子里管理了 1024 个句柄,loop 线程被唤醒的时候,select 都是蒙的,都不知道这 1024 个 fd 里谁 IO 准备好了。这种情况怎么办?只能遍历这 1024 个 fd ,一个个测试。假如只有一个句柄准备好了,那相当于做了 1 千多倍的无效功。
epoll 则不同,从 epoll_wait
醒来的时候就能精确的拿到就绪的 fd 数组,不需要任何测试,拿到的就是要处理的。epoll适合连接多,并发大,连接少可能select poll更好, 以为epoll 的通知机制需要很多函数回调。(红黑树)
同时epoll没有最大连接数限制,1G内存能监听约10w个端口;消息传递方式:select & poll 内核到用户空间,都需要内存拷贝,epoll通过内核和用户空间共享一块内存实现。
2、问题:
并发&并行的区别:并发是某一时刻,并行是时间段内。
单线程做高并发例子:epoll redis,nginx
fd设置成非阻塞,