为什么node.js在工作线程中管理异步繁重的文件系统调用,而一些网络操作不使用线程,而是在操作系统中使用本机异步API,允许主线程在网络操作完成时得到通知,而不会阻塞或旋转并等待它?难道不能用同样的方式处理异步文件系统调用,并将工作线程留给实际需要CPU能力来计算的密集型CPU绑定操作吗?
twh00eeo1#
Nodejs使用libuv作为其主要的跨平台库,用于操作系统调用。Libuv有一个跨平台的异步文件实现,它使用带有同步OS文件API调用的线程池,以便提供一致的异步文件API。线程池用于通过libuv API使同步OS调用异步运行。我个人并不了解整个libuv实现的历史,但我读到过,当操作系统支持的异步文件I/O接口还不成熟和可靠,或者在某些平台上不存在时,它就做出了这种架构选择。我知道Windows现在有异步文件I/O接口,但不知道libuv支持的所有其他平台。也可能是线程池实现工作正常,所以没有人优先考虑将其重新架构为更现代的异步OS文件I/O接口。难道不能用同样的方式处理异步文件系统调用,并将工作线程留给实际需要CPU能力来计算的密集型CPU绑定操作吗?Libuv现在可能可以重写为使用操作系统支持的异步API调用,但线程池工作正常,没有引起任何问题。请注意,正在使用的同步OS调用将阻塞,但它们不会旋转或浪费CPU。他们只是阻止线程。因此,它们在不需要线程的时候使用线程,但不会浪费CPU。而且,使用线程池意味着它可以有效地使用线程,而不是不断地创建和销毁它们,只是根据需要使用线程池。你会注意到libuv使用本地异步接口进行网络连接,因为这些接口在libuv支持的所有操作系统中已经存在很长时间了,这也是libuv最初的实现架构。仅供参考,线程池还用于提供一些异步加密API,其中不存在非线程异步实现。因此,线程池不太可能很快消失。
1条答案
按热度按时间twh00eeo1#
Nodejs使用libuv作为其主要的跨平台库,用于操作系统调用。Libuv有一个跨平台的异步文件实现,它使用带有同步OS文件API调用的线程池,以便提供一致的异步文件API。线程池用于通过libuv API使同步OS调用异步运行。
我个人并不了解整个libuv实现的历史,但我读到过,当操作系统支持的异步文件I/O接口还不成熟和可靠,或者在某些平台上不存在时,它就做出了这种架构选择。我知道Windows现在有异步文件I/O接口,但不知道libuv支持的所有其他平台。也可能是线程池实现工作正常,所以没有人优先考虑将其重新架构为更现代的异步OS文件I/O接口。
难道不能用同样的方式处理异步文件系统调用,并将工作线程留给实际需要CPU能力来计算的密集型CPU绑定操作吗?
Libuv现在可能可以重写为使用操作系统支持的异步API调用,但线程池工作正常,没有引起任何问题。请注意,正在使用的同步OS调用将阻塞,但它们不会旋转或浪费CPU。他们只是阻止线程。因此,它们在不需要线程的时候使用线程,但不会浪费CPU。而且,使用线程池意味着它可以有效地使用线程,而不是不断地创建和销毁它们,只是根据需要使用线程池。
你会注意到libuv使用本地异步接口进行网络连接,因为这些接口在libuv支持的所有操作系统中已经存在很长时间了,这也是libuv最初的实现架构。
仅供参考,线程池还用于提供一些异步加密API,其中不存在非线程异步实现。因此,线程池不太可能很快消失。