I/O多路复用

参考:https://www.zybuluo.com/phper/note/595507

https://github.com/CyC2018/Interview-Notebook/blob/master/notes/Linux.md

让单个进程具有处理多个I/O事件的能力。

当某个I/O事件条件满足时,进程会收到通知。

如果没有I/O多路复用,那么每一个socket连接都需要创建一个线程去处理,如果同时需要处理几万个连接那么就需要有几万个线程。相比于多进程和多线程,I/O多路复用不需要创建和切换线程进程的开销。

I/O模型:

阻塞、非阻塞:用户程序等待I/O事件的方式,阻塞要求用户程序停止执行一直到I/O发生,非阻塞在I/O完成之前可以继续执行。

同步、异步:获知I/O完成的方式,同步需要用户程序时刻关心I/O是否完成,异步不需要,当I/O完成时会收到通知。

同步-阻塞:用户程序执行read()后就会执行系统调用从而陷入内核,阻塞直到系统调用完成。

同步-非阻塞:用户程序执行系统调用后还可以继续执行,内核以一个错误码告知用户程序I/O尚未完成,为了获得I/O完成事件,用户程序必须调用多次系统调用查询内核。

异步:I/O操作后用户程序立即返回,当I/O完成时收到一个中断,此时用户程序中断当前操作,然后继续之前的操作。

实现:

select、poll、epoll

区别:

select、poll的区别:

当连接有I/O流事件发生时,就去唤醒进程处理。但是进程并不知道是哪个连接有事件发生,于是还是每个连接去询问。select能观察1024个连接,poll可以观察无限个连接。

epoll:

当发生I/O时间的时候,epoll会告诉进程哪个连接有I/O事件发生,然后进程就去处理这个事件。epoll是线程安全的。epoll不仅告诉你socket组里有数据,而且会告诉你哪个socket有数据。

epoll和select/poll最主要的区别:

epoll内部使用mmap共享了用户和内核的部分空间,避免了数据的来回拷贝。

epoll基于事件驱动,epoll_ctl注册事件并注册回调函数,epoll_wait只返回发生的事件,避免了select、poll对事件的整个轮询操作。

C10K问题:https://blog.csdn.net/yeasy/article/details/43152115

comments powered by Disqus