据我所知,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脚本都有自己的变量副本,因此您不会编写锁定代码。当然,其余部分完全不同,但据我所知,“您不必编写线程锁定代码”这一论点并不是一个好处,因为大多数数据都会被保存到其他地方(不是作为内存中的变量)。
答案 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访问正在进行时,线程可以自由处理其他请求/操作。这就是为什么它可以处理很多“同时”的连接。