确定哪个核心在运行时运行Node.js进程

时间:2015-05-28 03:57:53

标签: node.js

我正在查看'os'和'process'模块源代码,似乎没有办法确定node.js进程在运行之前/期间/之后运行的核心。

我正在寻找类似的东西:

process.env.CORE_ID   //not real

我只是想确认不同的node.js进程是在不同的核心上运行的。尽管操作系统最终选择执行node.js进程的核心,但我们应该能够在操作系统启动进程后读取该数据,这似乎是合理的。

4 个答案:

答案 0 :(得分:10)

进程没有附加到任何操作系统中的特定核心(除了,可能在某些实时导向的核心中)。

处理器(和核心)是可以在需要时分配给任何进程的资源。一个线程只能在一个核心中同时执行,但核心由所有进程共享。操作系统负责在可用核心上安排进程。因此,当任何进程由于允许在同一核心中执行(或继续执行)另一个进程而“暂停”时,没有理由期望下次在同一核心中恢复该进程。

当你通过简单地执行htop在具有相对低的cpu活动的(多核)机器中具有高cpu cosumption的单个进程时,这是可以观察到的。然后你可以看到总是有一个高度占用的核心,但核心是它将会定期改变。

答案 1 :(得分:6)

在试图思考为什么你想知道这种信息时,我想我理解你的困惑的核心。请注意,进程可以每毫秒多次切换核心。操作系统在安排这方面做得非常好,我无法想象性能是一个很大的问题,你需要对此进行改进(因为在这种情况下,你将编写自己的操作系统层,而不是在节点中)。在核心上运行的进程和必须在该核心上启动的进程之间绝对没有可观察到的延迟,除了可能在具有自定义操作系统的嵌入式硬件上。

请注意,现代系统甚至可以打开和关闭核心。因此,假设一个Web服务器具有2个核心和2个节点进程来处理请求。在没有太多工作的晚上,操作系统关闭核心2,两个进程都在核心1上运行愉快,为偶尔的请求提供服务。然后,当它变得更加繁忙时,操作系统启动第二个核心,并且大多数时间两个节点进程将同时运行,每个进程都在其自己的核心上。但请注意,操作系统还有许多其他进程(例如,更新实时时钟)。所以很可能在某些时候节点进程A运行在核心1上,节点进程B运行在核心2上。然后核心1用于更新时钟,而核心2仍在运行B.然而,中途更新时钟然而进程B在核心2上停止,并在那里启动进程A.完成时钟更新后,再次在核心1上启动进程B.所有这些都在不到一微秒的时间内完成。

因此,在现代架构上,上下文切换每秒发生数百万次,不要担心它们。即使您发现在某个时刻,2个节点进程在不同的核心上运行,也不能保证在一个微秒后仍然如此。而且,再次,操作系统可能会比你更好地优化它。

现在你可能感兴趣的是,知道是否由于某种原因这两个进程总是在同一个核心上运行(例如,因为它们秘密地不是两个进程,而是一个进程,例如对同一个进程的不同请求节点服务器)。这是你只需要检查一次的东西。只需完全加载两个节点实例,并检查top / process explorer / etc,如果它们的CPU使用率高于100%。如果是这样,您可以假设它们至少能够在不同的核心上运行,并进一步假设操作系统会将它们安排到不同的核心,如果他们可以从中受益。

答案 2 :(得分:3)

可能的linux方式:

function getPSR( pid, callback ) {
    var exec = require('child_process').execSync;

    var command = 'ps -A -o pid,psr -p ' + pid + ' | grep ' + pid + ' | grep -v grep |head -n 1 | awk \'{print $2}\'';

    var result = exec( command );

    return result.toString("utf-8").trim();
}

function getTIDs( pid ) {
    var exec = require('child_process').execSync;

    var command = 'ps -mo tid,psr -p ' + pid + ' | grep -v grep | awk \'/[0-9]/ {print("{\\042id\\042 : ", $1, ",\\042psr\\042:", $2, " }," )}\'';
    var tids = '[ ' + exec(command) + '{"id": false} ]';

    return JSON.parse(tids);
}

function setPSR( pid, psr ) {
    var exec = require('child_process').execSync;
    var command = 'taskset -pc ' + psr + ' ' + pid  + '; kill -STOP ' + pid + '; kill -CONT ' + pid;
    var result = exec(command);

    return result.toString("utf-8").trim();
}

function setTIDsPSR( pid, psr ) {
    var tids = getTIDs(pid);
    console.log(tids);
    for (var i in tids) {
    if (tids[i].id) {
        console.log( setPSR( tids[i].id, psr ) );
    }
    }
}

答案 3 :(得分:3)

试试这个https://www.npmjs.com/package/nodeaffinity

这适用于除OSX之外的基于Windows和Linux的操作系统。

var nc = require('nodeaffinity');

//Returns the cpus/cores (affinity mask) on which current node process is allowed to run 
//Failure returns -1 
console.log(nc.getAffinity()); 

//Sets process CPU affinity, here 3 means 011 i.e. process will be allowed to run on cpu0 and cpu1 
// returns same mask id success , if failure retuen -1. 
console.log(nc.setAffinity(3));
相关问题