为什么 Node.js 是单线程的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17959663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is Node.js single threaded?
提问by foreyez
In PHP (or Java/ASP.NET/Ruby) based webservers every client request is instantiated on a new thread. But in Node.js all the clients run on the same thread (they can even share the same variables!) I understand that I/O operations are event-based so they don't block the main thread loop.
在基于 PHP(或 Java/ASP.NET/Ruby)的 Web 服务器中,每个客户端请求都在一个新线程上实例化。但是在 Node.js 中,所有客户端都运行在同一个线程上(它们甚至可以共享相同的变量!)我知道 I/O 操作是基于事件的,因此它们不会阻塞主线程循环。
What I don't understand is WHY the author of Node chose it to be single-threaded? It makes things difficult. For example, I can't run a CPU intensive function because it blocks the main thread (and new client requests are blocked) so I need to spawn a process (which means I need to create a separate JavaScript file and execute another node process on it). However, in PHP cpu intensive tasks do not block other clients because as I mentioned each client is on a different thread. What are its advantages compared to multi-threaded web servers?
我不明白的是为什么Node的作者选择它是单线程的?它让事情变得困难。例如,我无法运行 CPU 密集型函数,因为它阻塞了主线程(并且新的客户端请求被阻塞),所以我需要生成一个进程(这意味着我需要创建一个单独的 JavaScript 文件并在其上执行另一个节点进程)它)。但是,在 PHP 中,cpu 密集型任务不会阻塞其他客户端,因为正如我所提到的,每个客户端都在不同的线程上。与多线程 Web 服务器相比,它的优势是什么?
Note: I've used clustering to get around this, but it's not pretty.
注意:我使用聚类来解决这个问题,但它并不漂亮。
回答by Chris Tavares
Node.js was created explicitly as an experiment in async processing. The theory was that doing async processing on a single thread could provide more performance and scalability under typical web loads than the typical thread-based implementation.
Node.js 是作为异步处理的实验明确创建的。理论是在单个线程上进行异步处理可以在典型的 Web 负载下提供比典型的基于线程的实现更高的性能和可扩展性。
And you know what? In my opinion that theory's been borne out. A node.js app that isn't doing CPU intensive stuff can run thousands more concurrent connections than Apache or IIS or other thread-based servers.
你知道吗?在我看来,这个理论已经得到证实。与 Apache 或 IIS 或其他基于线程的服务器相比,不执行 CPU 密集型任务的 node.js 应用程序可以运行数千个并发连接。
The single threaded, async nature does make things complicated. But do you honestly think it's more complicated than threading? One race condition can ruin your entire month! Or empty out your thread pool due to some setting somewhere and watch your response time slow to a crawl! Not to mention deadlocks, priority inversions, and all the other gyrations that go with multithreading.
单线程的异步性质确实使事情变得复杂。但是你真的认为它比线程更复杂吗?一个比赛条件可以毁掉你的整个月!或者由于某处的某些设置清空您的线程池,并观察您的响应时间缓慢到爬行!更不用说死锁、优先级反转以及多线程带来的所有其他问题。
In the end, I don't think it's universally better or worse; it's different, and sometimes it's better and sometimes it's not. Use the right tool for the job.
最后,我不认为它是普遍的更好或更坏;它是不同的,有时更好,有时则不然。为工作使用正确的工具。
回答by Kazaag
The issue with the "one thread per request" model for a server is that they don't scale well for several scenarios compared to the event loop thread model.
服务器的“每个请求一个线程”模型的问题在于,与事件循环线程模型相比,它们在多种场景下都不能很好地扩展。
Typically, in I/O intensive scenarios the requests spend most of the time waiting for I/O to complete. During this time, in the "one thread per request" model, the resources linked to the thread (such as memory) are unused and memory is the limiting factor. In the event loop model, the loop thread selects the next event (I/O finished) to handle. So the thread is always busy (if you program it correctly of course).
通常,在 I/O 密集型场景中,请求大部分时间都在等待 I/O 完成。在此期间,在“每个请求一个线程”模型中,链接到线程的资源(例如内存)未被使用,内存是限制因素。在事件循环模型中,循环线程选择下一个事件(I/O 完成)来处理。所以线程总是很忙(当然,如果你正确编程的话)。
The event loop model as all new things seems shiny and the solution for all issues but which model to use will depend on the scenario you need to tackle. If you have an intensive I/O scenario (like a proxy), the event base model will rule, whereas a CPU intensive scenario with a low number of concurrent processes will work best with the thread-based model.
作为所有新事物的事件循环模型看起来很闪亮,所有问题的解决方案都将取决于您需要解决的场景。如果您有密集型 I/O 场景(如代理),则事件基础模型将占主导地位,而具有少量并发进程的 CPU 密集型场景将最适合基于线程的模型。
In the real world most of the scenarios will be a bit in the middle. You will need to balance the real need for scalability with the development complexity to find the correct architecture (e.g. have an event base front-end that delegates to the backend for the CPU intensive tasks. The front end will use little resources waiting for the task result.) As with any distributed system it requires some effort to make it work.
在现实世界中,大多数场景都在中间。您需要在可扩展性的实际需求与开发复杂性之间取得平衡,以找到正确的架构(例如,有一个事件基础前端,将 CPU 密集型任务委托给后端。前端将使用很少的资源来等待任务结果。)与任何分布式系统一样,它需要一些努力才能使其工作。
If you are looking for the silver bullet that will fit with any scenario without any effort, you will end up with a bullet in your foot.
如果您正在寻找无需任何努力即可适应任何场景的灵丹妙药,那么您最终将被子弹击中。
回答by SheetJS
Long story short, node draws from V8, which is internally single-threaded. There are ways to work around the constraints for CPU-intensive tasks.
长话短说,node 来自 V8,它内部是单线程的。有一些方法可以解决 CPU 密集型任务的限制。
At one point (0.7) the authors tried to introduce isolates as a way of implementing multiple threads of computation, but were ultimately removed: https://groups.google.com/forum/#!msg/nodejs/zLzuo292hX0/F7gqfUiKi2sJ
在某一时刻 (0.7),作者试图引入隔离作为实现多线程计算的一种方式,但最终被删除:https: //groups.google.com/forum/#!msg/nodejs/zLzuo292hX0/ F7gqfUiKi2sJ

