【发布时间】:2013-07-31 08:18:09
【问题描述】:
在基于 PHP(或 Java/ASP.NET/Ruby)的网络服务器中,每个客户端请求都在一个新线程上实例化。但是在 Node.js 中,所有客户端都在同一个线程上运行(它们甚至可以共享相同的变量!)我知道 I/O 操作是基于事件的,因此它们不会阻塞主线程循环。
我不明白为什么 Node 的作者选择它是单线程的?它使事情变得困难。例如,我无法运行 CPU 密集型函数,因为它阻塞了主线程(并且新的客户端请求被阻塞),所以我需要生成一个进程(这意味着我需要创建一个单独的 JavaScript 文件并在其上执行另一个节点进程它)。但是,在 PHP 中,CPU 密集型任务不会阻塞其他客户端,因为正如我所提到的,每个客户端都在不同的线程上。与多线程 Web 服务器相比,它有哪些优势?
注意:我已经使用集群来解决这个问题,但它并不漂亮。
【问题讨论】:
-
我最近看了一个很好的视频(29 分钟),解释了 Node.js 背后的一些理论。我什至认为这家伙谈到了 CPU 密集型任务以及如何处理它们:youtube.com/watch?v=L0pjVcIsU6A
-
你可能知道这一点,但要清楚 Node.js 不是单线程的。您的 JavaScript 代码运行单线程,但 IO 操作和插件可以执行的其他操作在线程池之外运行。 Node.js 为您提供了多线程的许多好处,而无需处理多线程代码。此外,Node.js 的贡献者并没有选择 JavaScript 的单线程特性,JavaScript 的作者选择了。我想不出一种 JS 可以在多线程上下文中工作的方式,但即使有,V8 也不是 Node.js 用作其 JavaScript 引擎的那种方式编写的。
-
PHP 比 JavaScript 更单线程。您可能正在考虑像 FastCGI 或 mod_php 这样的服务器模块。因此,您实际上是在将 Node.js 与 Apache、Nginx 或 IIS 进行比较,而不是与 PHP、Java 或 Ruby 进行比较。
-
节点不是单线程的。这是一个流行的误解。即使是简单的
node -e 'setTimeout(()=>{},1000);' & ps -T h $! | wc -l; kill $!也会在我的系统上显示五个线程。主 事件循环 是单线程的(如果不是这样就没有多大意义),但 Node 是多线程的,如果你愿意,你可以编写多线程的单进程应用程序.我很想写一个关于它的全面答案,但有些人决定关闭你的问题,所以我不能。我正在投票重新开放它。如果它获得更多选票并重新开放,请在评论中提及我。 -
@rsp 感谢您的评论,但我的意思是在主线程中与 i/o 无关。如果您正在执行与 cpu 相关的操作,例如执行某些操作的大 for 循环,则服务器将停止处理连接。意思是,服务器当时不可用。所以我们只能使用像集群这样的黑客来做一些如此简单的事情,而不是像大多数服务器那样固有地线程化每个连接。 jxcore.com 试图解决这个问题,但后来它使用了特殊/修改过的节点插件,这基本上使它对我来说无法使用。
标签: node.js