Jez*_*Jez 7 multithreading multicore node.js
我已经看过一些关于在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);
});
}
Run Code Online (Sandbox Code Playgroud)
该Node.js的文档是出奇的糟糕,并给出了很少的信息cluster.fork([env]):
产生一个新的工人流程.
这只能从主进程调用.
所以它说的是它产生了一个新的工人流程.我们怎么知道,这将在一个新的CPU核心来催生,如果我们产卵额外的过程,当我们已经有了对我们每个CPU核心中的至少一个过程中,会发生什么?
以下是关于现代操作系统(如Linux,Windows,FreeBSD)上的进程和线程的一般观点.操作系统根据许多事情管理线程/进程动态运行的核心(例如,哪个核心"最接近"存储进程数据的内存[这在双CPU机器上有点重要],哪个内核是免费的,等等).动态地,因为它可以很好地将核心时间片切换到时间片(例如,每秒60次).
不要忘记,在SMP硬件平台中,将线程从一个核心移动到另一个核心并没有真正的性能损失 - 这主要是核心程序计数器寄存器指向的位置.还有其余的进程上下文,但这只是一堆CPU寄存器值,大多数情况下.实际上,如果您有2个或更多CPU,现代英特尔平台不是纯粹的SMP.它们之间的Quickpath互连用于从实际上是NUMA的东西合成SMP硬件架构.Quickpath就像是两台独立计算机之间的高速网络连接,速度足以传输数据,缓存同步等,这样其他CPU的RAM上保存的数据几乎可以像在CPU的RAM上一样快速地访问.
对于一个应用程序(例如Node.JS运行时)来控制最终运行的核心实际上是非常困难的,而且通常是毫无意义的; 可以信任操作系统来完成管理以获得最佳性能的最佳工作.手动控制是毫无意义的.我曾尝试过一次出于兴趣(使用一些实时信号处理代码),并且无法从系统中获得更多性能,而不仅仅是让操作系统自然地代表我管理核心关联.
因此,当您调用cluster.fork()时(假设"生成另一个工作进程"实际上意味着启动另一个进程),那么新操作系统将在操作系统认为最符合当时环境的情况下运行,并且将会当进程阻塞,准备好运行,被另一个进程抢占等等时,它会不断地在核心周围反弹.
产生比CPU核心更多的进程可能是一件好事.如果它们阻塞了很多(例如等待输入),那就没问题了.在这种情况下,它们会阻塞,操作系统会对它们进行计划,如果某些数据出现在套接字上,或者重新安排必要的数据以处理数据.如果它们不断处理,那么最好将进程/线程数与CPU内核数相匹配,以最大限度地减少上下文切换所浪费的时间.
因此,您只是冒险在计算机上同时运行其他任何东西,以防止操作系统将您的4个进程分散到4个核心.
如果您正在同时运行文字处理器,那么当您没有打字时,这几乎是静止的(即,等待键盘输入被阻止),所以没有问题.在输入数据实际到达之前,操作系统不会(实际上不能)安排等待输入的进程.信号量,互斥量等也是如此
相比之下,启动Web浏览器并将其指向包含大量视频广告的页面将导致浏览器占用大量CPU时间.那是因为总有数据要处理(视频流),解码需要大量数学.
还有进程优先级作为另一个维度.如果您已将流程标记为高优先级,则操作系统将在其他流程之前安排它们.
操作系统安排线程/进程在所有人中实现最大化,努力公平地对待系统中的每个进程.大多数操作系统将在每个核心上决定每秒运行大约60次.最终结果是看起来一切都在平行运行,但实际上一切都在轮流进行.进程优先级是一种在每秒执行60次决策时使操作系统偏向更高优先级进程的方法.
Windows是独一无二的,它将当前具有鼠标焦点的过程赋予人工优先级 - 使其外观和感觉更加快捷.那个日期一直追溯到Windows 3.0我想!
| 归档时间: |
|
| 查看次数: |
1410 次 |
| 最近记录: |