cluster.fork()是否保证使用不同的CPU核心?

时间:2016-09-08 14:20:01

标签: node.js multithreading multicore

我看过很多关于在node.js中使用集群来使用所有CPU核心的教程,但它们似乎都暗示运行cluster.fork()将使用新的CPU核心;例如:

if (cluster.isMaster) {
    cluster.setupMaster({
        exec: 'bin/www'
    });

    // Fork workers
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    Object.keys(cluster.workers).forEach(function (id) {
        console.log('Worker id: ' + id + ' with pid: ' + cluster.workers[id].process.pid);
    });
}

node.js documentation非常糟糕,并且对cluster.fork([env])提供的信息非常少:

  

产生一个新的工作进程。

     

这只能从主进程调用。

所以它说的是它产生了一个新的工作进程。我们怎么知道这将在新的CPU内核上产生,如果我们在每个CPU内核上至少有一个进程产生额外的进程会发生什么?

2 个答案:

答案 0 :(得分:7)

以下是关于现代操作系统(如Linux,Windows,FreeBSD)上的进程和线程的一般观点。操作系统根据许多事情管理线程/进程动态运行的核心(例如,哪个核心与保存进程数据的内存最接近[这对双重问题有点重要] CPU机器],核心是免费的,等等。动态地,因为它可以很好地将核心时间片切换到时间片(例如,每秒60次)。

不要忘记,在SMP硬件平台中,将线程从一个核心移动到另一个核心并没有真正的性能损失 - 它主要只是核心位置的问题。程序计数器寄存器指向。还有剩下的进程的上下文,但这只是一堆CPU寄存器值,大多数情况下。实际上,如果您有2个或更多CPU,现代英特尔平台不是纯粹的SMP。它们之间的Quickpath互连用于从实际上是NUMA的东西合成SMP硬件架构。 Quickpath就像两台独立计算机之间的高速网络连接,速度足以传输数据,缓存同步等,使得其他CPU的RAM上保存的数据几乎可以像在CPU上一样快速地访问&# 39; s RAM。

对于一个应用程序(例如Node.JS运行时)来控制它最终运行的核心实际上是非常困难的,而且通常是毫无意义的;可以信任操作系统来完成管理以获得最佳性能的最佳工作。手动控制是毫无意义的。我曾经尝试过一次兴趣(使用一些实时信号处理代码),并且无法从系统中获得更多性能,而不仅仅是让操作系统自然地代表我管理核心关联。

所以当你调用cluster.fork()时(假设&#34;产生另一个工作进程&#34;实际上意味着启动另一个进程)然后新的那个将在操作系统认为最好的地方运行对于当时普遍存在的情况,当进程阻塞,准备运行,被另一个进程抢占等时,它将不断地在核心周围反弹。

产生比CPU核心更多的进程可能是一件好事。如果他们阻止很多(例如等待输入),那就没问题了。在这种情况下,它们会阻塞,操作系统会对它们进行计划,如果某些数据出现在套接字上,或者重新安排必要的数据以处理数据。如果他们不断进行处理,那么最好将进程/线程数与CPU核心数相匹配,以最大限度地减少上下文切换所耗费的时间。

修改

因此,您只是冒险在计算机上同时运行任何其他内容,以防止操作系统将您的4个进程分散到4个核心。

如果您同时运行文字处理程序,那么当您没有打字时,这几乎是静止的(即,等待键盘输入被阻止),所以没有问题。操作系统不会(确实可以)安排一个等待输入的进程,直到输入数据实际到达为止。信号量,互斥量等也是如此。

相比之下启动Web浏览器并将其指向包含大量视频广告的页面将导致浏览器占用大量CPU时间。那是因为总是需要处理的数据(视频流),解码它需要大量的数学。

还可以将优先级作为另一个维度来处理。如果您已将流程标记为高优先级,则操作系统将在其他流程之前安排它们。

操作系统安排线程/进程在所有方面实现最大化,努力公平地对待系统中的每个进程。大多数操作系统将在每个核心上决定每秒运行大约60次。最终结果是看起来一切都在平行运行,但实际上一切都在轮流进行。进程优先级是一种使操作系统在每秒执行60次决策时偏向更高优先级进程的方法。

Windows在将当前具有鼠标焦点的过程赋予人工优先级提升方面是独一无二的 - 使其外观和感觉更加快捷。那个日期一直追溯到Windows 3.0我想!

答案 1 :(得分:0)

不,操作系统确定将安排进程运行的核心。群集模块将简单地生成许多单独的Node.js进程,以便您的程序可能同时在多个核心上运行(并行)。

这通常通过让每个衍生的Node.js进程成为服务器(具有非共享内存)的单独实例来实现,所有这些实例都在同一端口上进行侦听。因此,您实际上是在服务器的多个实例之间拆分传入HTTP请求的工作负载。