如果所有节点.js的工作线程都繁忙,会发生什么情况

What happens if all node.js's worker threads are busy

本文关键字:什么情况 线程 节点 js 工作 如果      更新时间:2023-09-26

我试图了解node.js的工作原理,尽管我已经阅读了这篇文章:何时使用线程池?我不确定如果所有工作线程都繁忙并且另一个异步 I/O 操作已准备好执行会发生什么。

如果我对 http://www.future-processing.pl/blog/on-problems-with-threads-in-node-js/这篇文章是正确的,则事件循环将被阻塞,直到工作线程可以自由地处理额外的 I/O 操作。这意味着,如果五个用户尝试同时访问一个网页(比如他们的个人资料页面,比如说需要一个数据库查询),第 5 个用户将被阻止,直到第一个数据库查询完成并且这个工作线程再次空闲?

I/O 通常不会阻塞事件循环(有一些例外,例如当前的 crypto 模块和 fs.*Sync() 方法之类的东西),尤其是在网络 I/O 的情况下,libuv 线程池根本不使用(仅用于 DNS(当前)和 fs 操作之类的东西)。

如果您的数据库驱动程序是用 C++ 编写的 node.js 插件,则它有可能阻塞事件循环(它正在执行同步操作),或者它可能正在使用 libuv 线程池。但是,如果数据库驱动程序仅用 JavaScript 编写,它通常使用某种网络 I/O,如前所述,它不会阻止任何内容,也不会使用 libuv 线程池。

因此,在您的示例中,根据数据库驱动程序的实现方式,可以同时为所有 5 个用户提供服务。例如,协议级别的MySQL每次仅支持一个未完成的查询。因此,大多数 node.js 的 MySQL 驱动程序将做的是将其他查询排队,直到当前查询完成。但是,MySQL 驱动程序完全有可能在内部维护某种连接池,以便您拥有更大的并发性。

但是,如果 5 个请求中的每一个都导致某些内容来自磁盘,那么由于 libuv 线程池的当前默认大小,第 5 个请求可能必须等到其他 4 个 fs 请求中的一个完成。这并不意味着事件循环本身被阻塞,因为它仍然可以为新的传入请求和其他东西提供服务,但第 5 个客户端只需要等待更长的时间。

在工作线程中执行的操作是否有任何类型的队列?

是的。libuv 管理此队列。所有工作线程都可能被占用,在这种情况下,转到工作线程池的新异步请求将不会取得进展。请注意,"异步 FS 请求"仍必须在某处完成,并且将阻止正在处理它的工作线程,直到它完成。