2016-09-20 85 views
6

我一直在寻找更多的并发和并行的区别。我在Rob Pike的演讲中谈到了并发与并行之间的差异。他的演讲是在Google Go语言的背景下进行的。根据我的理解,并发性是能够处理多种事物的设计,但并行是同时执行多个事物的物理过程。Node.js是否支持并行?

从我也明白,Node.js作为一个单线程进程运行。因此,虽然Node支持并发执行回调等方式,它是否有能力处理任务的并行执行?它可以设置为在单独的处理器上运行多个线程吗?

回答

4

节点可以支持“并行”通过打包在核心的NodeJS API中Clusterchild_process模块。这两个模块创建额外的进程,而不是额外的线程。

线程被创建和管理,有时在池中,被libuv“引擎盖下”,node实现并用于执行异步操作,例如从文件读取。 您无法从正在执行的Javascript中显式创建线程。您可以在下面的参考资料

此外,这是对Threads and Pooling大问题里面有很多的细节。

Cluster用于将服务器的工作负载分布到多个内核中,并仍然让它们共享一个端口。但是,Cluster在引擎盖下使用child_process.fork(),并通过inter-process communication进行通信。你可以阅读更多关于Cluster in the Nodejs Core API Docs

child_process通过exec()spawn()fork()提供了几种不同的方式来并行化工作。父进程可以通过管道使用进程间通信与子进程进行通信。

基本上,Node希望您利用the event loop并将线程管理保留为libuv。这就是为什么构建通常需要锁定和线程安全措施的代码非常容易。如果您必须完成需要繁重工作或大量阻塞(同步)工作的工作,则可以使用child_process来卸载该工作。如果您需要跨核心扩展Web应用程序,请使用Cluster

+0

我的印象是,至少有[单向](https://www.npmjs.com/package/webworker-threads)创建多个可同时运行的执行流,通过将消息传递给彼此。那不是吗? –

+1

@DavidSchwartz,不,你是对的,那种方法可以使用'child_process'和实现消息传递,在父进程中使用'child_process.on('message')'事件并且在子进程中使用'process.send()'函数处理。我也想限制我对Node.js作为其核心功能的一部分提供的答案,而不是可能提供哪些软件包。 – peteb

0

如果我没有弄错,你正在寻找沿着多线程和/或同时计算多个事物的东西。

多次执行一次
SIMD正开始找到自己的方式进入浏览器,与节点的实现也不甘落后。看看node-simdMDN SIMD (browsers)。 SIMD仍然是实验性的,只能在当前支持的CPU上运行(显然,因为并非所有CPU都具有此功能)。它同时执行多重的东西,比较正常JS为例SIMD JS是:

// Normal addition, 4 actions are executed. 
var a = [1, 2, 3, 4]; 
var b = [5, 6, 7, 8]; 
var c = []; 

c[0] = a[0] + b[0]; 
c[1] = a[1] + b[1]; 
c[2] = a[2] + b[2]; 
c[3] = a[3] + b[3]; 
c; // Array[6, 8, 10, 12] 

// SIMD execution - all additions are processed simultaenously through the CPU 
var a = SIMD.Float32x4(1, 2, 3, 4); 
var b = SIMD.Float32x4(5, 6, 7, 8); 
var c = SIMD.Float32x4.add(a,b); 
c; // Float32x4[6, 8, 10, 12] 

多线程
在关于多线程,webworkers已经在了,而浏览器环境目前业已。根据HTML规范,这已完全移植到Node上,如in this repository所示。
下面是good explanation为什么webworkers甚至首先被移植到Node,因为您已经可以在child_process模块的其他线程和其他CPU上运行子进程。 node-webworker是一个很好的模块,因为每个进程都在其上下文中运行,并且在其自己的node进程中运行,所以它实际上是与节点进行多线程的。

因此,要在不同的CPU上运行不同的进程,您要么采用node-webworker,要么使用child_process产生其他线程,以便与不同的CPU核心同时执行不同的操作。 node-webworker可以使用熟悉的postMessage API监听事件,并且child_process将通过stdin/stdout/stderr进行通信。

希望这回答你的问题:)