gpt4 book ai didi

javascript - Node JS 异步 I/O 执行

转载 作者:太空宇宙 更新时间:2023-11-04 03:08:57 25 4
gpt4 key购买 nike

据我了解,虽然表面上有一个“辅助”线程,但 Node.js 在单个线程中运行,因此,事件循环堆栈中的每个操作都在一个接一个地运行,而其他操作则在 Node 在后台执行异步 I/O 时排队,这样服务器就能够在执行非阻塞 I/O 的同时执行其他操作,而不需要创建浪费的多个线程,I/O 完成并将其关联的回调拉入事件循环队列,这就是 Node 的重要之处。

但是,在我准备的许多文章中,并不清楚异步 I/O 操作是否与 I/O 单独线程或进程中的其他 I/O 操作并行运行,或者每个请求的 I/O 操作是否在事件循环执行其他操作时在辅助线程中相继运行。在读完“除了你的代码之外,一切都是并行运行的”这句话后,这让我更加困惑。

问题是,多线程还是非多线程?如果每个异步操作都在单独的线程中运行,它是否会像 Apache 服务器一样使用尽可能多的资源?

最佳答案

Node 本质上是非多线程的。异步性比 Node 更深,比 libuv 更深,甚至比 libuv 使用的工具(epollkqueueIOCP 等)更深。

当内核收到异步请求时,它不会启动另一个执行线程。相反,它将其添加到一个简单的“需要注意的事项”列表中。例如,如果一个进程发出网络读取请求,内核将在该列表上创建一个条目。就像“嘿,下次有类似这样的读取请求时,让进程知道它。”完成此条目后,内核将控制权返回给进程,然后两者都继续快乐地生活。唯一幸存下来的是列表中的数据。

通过 hardware interrupts. 向内核通知网络读取事件使用中断,处理器将内核拉入一个特殊的循环 - 停止当前正在执行的任何操作 - 并告诉它有关事件的信息。然后,内核检查其未完成请求列表,并(在 kevent AIO 情况下)向进程发送类似的中断(以信号的形式),以使其了解网络读取情况。所以,没有线程。只是打扰。

嗯,这有点简化:在非 AIO kevent 和 epoll 情况下,内核获得网络读取后,它只会将其放入事件列表中。该进程定期检查该事件列表以查看是否有事件发生。

此外,从内核 Angular 来看,这就是所有 I/O 的工作方式。最大的区别是内核不需要进程等待内核返回它。

实际上有a little more complexity在 libuv 中,非网络请求(以及 DNS 请求,这是一种特殊的、痛苦的网络请求形式)是由线程处理的。这是因为用于使这些异步的内核设施通常不是那么好,如果它们存在的话。

关于javascript - Node JS 异步 I/O 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30204750/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com