0

据我了解,NodeJS 的好处之一是每个进程一个线程;在标准情况下,您无需担心并发性。

我还阅读了关于多核机器上的 NodeJS 缩放(多核机器上的 Node.js):

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

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

或者如果它们不并行执行......多核的提升/好处来自哪里?


编辑:我目前的理解

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

例如:

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 脚本都有自己的变量副本,因此您无需编写锁定代码。当然,其余部分完全不同,但据我所知,“你不必编写线程锁定代码”这一论点并没有多大好处,因为无论如何大多数数据都会保存在其他地方(不是作为内存变量)。

4

3 回答 3

2

答案:

nodejs 在多核上运行时是否具有“单线程”(无多线程锁定代码)优势?

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

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

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

于 2013-05-24T04:32:27.440 回答
2

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

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 可以具有多核执行模式。这可以通过将 Javascript 代码集群(分叉)到各种 nodeJS 进程中或通过产生子进程来实现。同样,在每个单独的进程(集群或子进程)中,竞争条件不会发生在它们的内部资源中。当他们交换 资源时两者都不会发生,因为在任何时候双方都只执行一段代码并应用交换。

但您也提到了外部资源,例如 MongoDB。NodeJS 不能不知道 MongoDB 在任何时候提供的服务,而不是它自己的调用。所以在那种情况下竞争条件(我不完全确定mongoDB 如何为这种情况服务,这只是一个假设)可以随时发生,因为 MongoDB 可以随时为任何进程提供服务,第二个进程是 NodeJS 的 fork 实例或任何其他进程。在这种情况下,您应该实施锁定机制。

您应该注意,同样的情况也适用于Actor 模式,其中每个 Actor 都是一个单独的线程,并且具有非常相似的方式来处理对其线程内部资源的竞争条件。但是当涉及到 Actor 的性质的外部资源时,不可能知道外部资源的状态。

只是深思熟虑,你为什么不检查一个不可变的 机制

干杯!

于 2013-05-24T07:42:33.657 回答
0

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

于 2013-05-24T04:32:35.767 回答