在多个内核上运行时,nodejs是否带有“单线程”(没有多线程锁定代码)的好处?

时间:2013-05-24 04:23:58

标签: node.js concurrency

据我所知,NodeJS的一个好处是它是每个进程一个线程;在标准情况下,您不必担心并发。

我还了解了多核计算机上的NodeJS扩展(Node.js on multi-core machines):

  

工作人员将竞争接受新的连接,并且负载最少的进程最有可能获胜。它运行良好,可以在多核盒上很好地扩大吞吐量。

在这种情况下,多个线程会并行执行吗?如果是这样,这是否意味着我们必须编写多线程代码(如果我们想使用多个内核) - 如果是这样,我该怎么做?

或者,如果它们不并行执行......多个内核的增益/收益来自何处?


修改:我目前的理解

因此,多个核心上可能有多个进程,但每个进程只有一个线程。

例如:

var io = require('socket.io').listen(81);

var connections = [];

io.sockets.on('connect', function (socket) {
    console.log('connected...');
    connections.push(socket);

    socket.on('disconnect', function () {
        console.log('disconnected');
        connections.remove(socket);
    });
});

没有种族关系;有一个线程,不会有connections的并发访问。当您有不同的流程时,每个流程都有自己的connections副本。因此,如果你有一个庞大的聊天室,你无法平衡负载与多个进程;每个过程都是它自己的聊天室。

在这方面,它与PHP没有任何不同,因为每个PHP脚本都有自己的变量副本,因此您不会编写锁定代码。当然,其余部分完全不同,但据我所知,“您不必编写线程锁定代码”这一论点并不是一个好处,因为大多数数据都会被保存到其他地方(不是作为内存中的变量)。

3 个答案:

答案 0 :(得分:2)

答案:

  

在多核上运行时,nodejs是否带有“单线程”(没有多线程锁定代码)的好处?

是的,节点仍然会阻止锁定代码,因为每个进程仍然是单线程的。

节点中没有多线程(javascript被设计为单个线程)。扩展到多核涉及多个进程,每个进程都有一个单独的线程。

因此,您有多个并行执行的进程,但由于它们是独立的进程,并且具有自己的进程空间,因此您不会像使用多线程进程那样遇到锁定问题。进程之间的通信使用IPC通过句柄。由于所有IO在Node中都是非阻塞的,而子进程在等待I / O,其他进程可以继续执行并接收数据。

答案 1 :(得分:2)

由于javascript的性质,运行代码只能在单个Thread中执行。这意味着在运行节点的每个内部资源中,每个资源只能由一个正在运行的函数访问,并行性不会发生。 一个例子:

var car = {
    velocity: 100,
};

function speedUpTo150() {
    car.velocity = 150;
}

function slowDownTo80() {
    car.velocity = 80;
}

speedUpTo150();
slowDownTo80();
setTimeout(function() {
    speedUpTo150();
},1000);

setTimeout(function() {
    slowDownTo80();
},1000);

通过这个例子,应该很清楚,竞争条件不会发生,因为任何时候访问car只能有一个功能。

然而,如您所提到的nodejs可以具有多核执行模式。这可以通过by clustering (forking)将Javascript代码发送到各种nodeJS进程中,或者通过spawing child Processes发生。同样在每个单独的进程(集群或子进程)中,竞争条件不会发生在其内部资源中。它们exchange resources都不会发生,因为在任何时候双方只执行一段代码并应用交换。

但是你也提到了外部资源,比如MongoDB。 NodeJS无法随时了解MongoDB所服务的内容,而不是自己的调用。因此,在这种情况下,竞争条件(我不完全确定how mongoDB serves this case,它只是一个假设)可能发生,因为MongoDB可以在任何时间为任何进程提供服务,或者第二个进程是NodeJS的fork实例或任何其他进程。在这种情况下,您应该实现锁定机制。

你应该注意到同样的情况也适用于Actor pattern,其中每个actor都是一个单独的线程,并且有一种非常类似的方法来处理其线程内部资源的竞争条件。但是当谈到外部资源时,就不可能了解外部资源的状态。

只是值得深思,为什么不检查immutable mechanism

干杯!

答案 2 :(得分:0)

JavaScript总是在一个线程中运行。 JavaScript中没有多线程代码。它对于繁重的计算并不好,但它对基于IO的操作有好处,因为它基于事件,例如,当IO访问正在进行时,线程可以自由处理其他请求/操作。这就是为什么它可以处理很多“同时”的连接。