阻塞I/O模式下,一个线程只能处理一个流的I/O事件(比如用户线程发起一个IO请求操作,内核会去查看要读取的数据是否就绪,如果数据没有就绪,则会一直在那等待,直到数据就绪,当数据就绪之后,便将数据拷贝到用户线程)。
所以,如果想要同时处理多个流,要么多进程(fork),要么多线程(pthread_create),很不幸这两种方法效率都不高。
select/poll 的弊端
考虑非阻塞忙轮询的I/O方式,我们发现同时处理多个流,使用select,我们有O(n)的无差别轮询复杂度,同时处理的流越多,每一次无差别轮询时间就越长。
select/poll是通过轮询的方法来获得就绪的状态,调用select/poll后就阻塞住,直到有就绪的文件描述符,或者超时,或者被中断。返回值是就绪的文件描述符的个数,需要遍历作为参数传入的文件描述符的位域或数组获得文件描述符。
Kqueue和Epoll的优势
epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll之会把哪个流发生了怎样的I/O事件通知用户空间程序。此时我们对这些流的操作都是有意义的。关于 epoll 的应用参考连接。
kqueue与epoll非常相似,在注册一批文件描述符到 kqueue 以后,当其中的描述符状态发生变化时,kqueue将一次性通知应用程序哪些描述符可读、可写或出错了(即产生事件Event)。
kqueue 支持的event很多,文件句柄事件,信号,异步io事件,子进程状态事件,支持微秒的计时器事件等。
https://blog.csdn.net/weixin_38387929/article/details/118584182