我正在研究异步IO、IO的并发模型以及windows、linux和大多数使用的web框架上的工作方式。
我很难理解为什么像node.js或ngnix那样的单线程事件循环在处理想要进行IO操作的请求时(比如从另一个服务获取数据的HTTP请求)使用一个专用线程来处理每个IO操作,而不是使用一个线程和Epoll来处理所有这些操作。
让我更好地解释:
那么,使用Epoll或其他多路复用库来保存用于管理传入请求的线程计数又有什么意义呢?如果我最终能够为管理每个已处理的请求所需的IO操作执行大量上下文切换?为什么不使用Epoll在单个(或少数)线程上“批处理”这些IO操作?
发布于 2021-04-27 13:23:43
Select和Epoll过去和现在都是有缺陷的API。它们有效地告诉我们,如果在特定的文件描述符上可以执行I/O操作,但实际上不允许我们以异步的方式执行I/O操作:一旦执行读或写,就会被阻塞,直到该操作完成为止。
因此,常见的解决方法是将潜在阻塞的I/O操作委托给线程池(每个操作不是一个线程)。这是相当有效的,因为这些线程将大部分时间用于I/O操作(无论是在syscalls上还是在等待主线程的新I/O任务上)。向I/O线程池发送任务不需要上下文切换。打开的连接数可以远远高于当前正在执行的I/O操作数。
有更好的方法可用,特别是Windows开创的完成端口。在5.1版(2019年5月)的io_uring中,Linux终于获得了完全异步的I/O。
https://softwareengineering.stackexchange.com/questions/425821
复制相似问题