2015-05-28 8 views
5

Stavo osservando l'origine del modulo 'os' e 'processo' e non sembra essere un modo per determinare su quale core un processo node.js è in esecuzione, prima/durante/dopo il runtime.Determinare quale core esegue il processo Node.js in fase di esecuzione

Sto cercando qualcosa di simile:

process.env.CORE_ID //not real 

Voglio solo confermare che i processi differenti Node.JS sono in esecuzione su diversi core. Sembra ragionevole che, sebbene il sistema operativo scelga alla fine su quale core viene eseguito un processo node.js, dovremmo essere in grado di leggere quei dati una volta che il sistema operativo avvia il processo.

risposta

8

Il processo non è collegato a un core specifico in alcun sistema operativo (tranne, forse, in alcuni casi in tempo reale).

I processori (e core) sono risorse che possono essere assegnate a qualsiasi processo ogni volta che è necessario. Un thread può essere eseguito solo in un singolo core contemporaneamente, ma i core sono condivisi da tutti i processi. Il sistema operativo è responsabile della pianificazione dei processi rispetto ai core disponibili. Quindi, quando un processo viene "messo in pausa" per consentire l'esecuzione (o il proseguimento dell'esecuzione) di un altro processo nello stesso core, non c'è motivo di aspettarsi che il processo venga ripreso nello stesso core la volta successiva.

Questo è scarsamente osservabile quando si ha un singolo processo con un consumo di cpu alta in una macchina (multi-core) con un'attività di cpu relativamente bassa semplicemente eseguendo htop. Quindi si può vedere che c'è sempre un nucleo altamente occuppato, ma quale nucleo cambierà regolarmente.

+0

bene, la seguente dichiarazione è solo una congettura, ma forse c'è una piscina di CPU disponibili per eseguire un processo e si può dettare quali piscina iis disponibile quale processo? Forse puoi parlare del modo in cui il modulo del nucleo principale di Node.js si adatta a quello che stai dicendo. –

+1

No. La pianificazione delle processess (o dei thread) è una competenza esclusiva del sistema operativo. Puoi chiedergli di creare un nuovo processo (o thread), ma non puoi decidere su quali processori fisici lo eseguiranno. Non sono sicuro di poter essere confuso con il pool di thread Node che, in effetti, è un pool di ** thread ** dedicato a partecipare simultaneamente alle operazioni asincrone. Vedi http://www.future-processing.pl/blog/on-problems-with-threads-in-node-js/ – bitifet

+0

grazie, come posso accedere al pool di thread Node.js da un processo node.js? –

3

modo possibile 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)); 
    } 
    } 
} 
+0

grazie, ci proveremo presto a breve –

5

Durante il tentativo di riflettere sul perché si vorrebbe conoscere questo tipo di informazioni, credo di aver capito il nucleo della vostra confusione. Nota che un processo può cambiare core più volte al millisecondo. Il sistema operativo fa un ottimo lavoro di pianificazione di questo, e non posso immaginare che le prestazioni siano un problema di cui dovresti migliorare (perché in questo caso dovresti scrivere il tuo livello OS e non nel nodo). Non ci sarà assolutamente alcun ritardo osservabile tra un processo che gira su un core e che deve essere avviato su quel core, tranne eventualmente su hardware embedded con un sistema operativo personalizzato.

Si noti che i sistemi moderni possono anche attivare e disattivare i nuclei. Quindi immagina un server web con 2 core e 2 processi di nodo che servono le richieste. Di notte, quando non c'è molto lavoro, il sistema operativo spegne il core 2 e entrambi i processi funzionano felicemente sia sul core 1, sia su richiesta occasionale. Quindi, quando diventa più impegnativo, il sistema operativo avvia il secondo core e la maggior parte delle volte i due processi del nodo verranno eseguiti contemporaneamente, ciascuno sul proprio core. Tuttavia, si noti che il sistema operativo ha anche molti altri processi (ad esempio, l'aggiornamento dell'orologio in tempo reale). Quindi potrebbe benissimo essere che ad un certo punto il processo A del nodo viene eseguito sul core 1 e il processo B sul nodo 2. Quindi il core 1 viene utilizzato per aggiornare l'orologio, mentre il core 2 è ancora in esecuzione B. A metà l'aggiornamento dell'orologio comunque il processo B viene arrestato sul core 2 e il processo A viene avviato lì. Al termine dell'aggiornamento dell'ora, il processo B viene riavviato sul core 1. Tutto ciò avviene in meno di un microsecondo.

Quindi gli switch di contesto avvengono milioni di volte al secondo su architetture moderne, non preoccuparti di loro. Anche se a un certo punto si scopre che i processi a 2 nodi sono eseguiti su core diversi, non è garantito che questo sia ancora vero un microsecondo dopo. E, di nuovo, probabilmente il sistema operativo farà un lavoro molto migliore per l'ottimizzazione di te.

Ora una cosa che potrebbe interessarti, è sapere se non per qualche motivo i due processi SEMPRE vengono eseguiti sullo stesso core (ad es.perché segretamente non sono due processi, ma un processo, come richieste diverse allo stesso server nodo). Questo è qualcosa che devi controllare solo una volta. Basta caricare completamente entrambe le istanze del nodo e controllare top/process explorer/etc se il loro utilizzo combinato della CPU è superiore al 100%. In tal caso, si può presumere che siano almeno in grado di girare su diversi core e supporre inoltre che il sistema operativo li pianifichi su core diversi se ne trarrebbero vantaggio.

+0

grazie Claude, è vero, voglio sapere quando si avvia più di un processo Node.js, se i processi stanno effettivamente utilizzando più core sulla macchina. Prima di leggere queste risposte, pensavo che un processo Node.js potesse essere eseguito solo su un core; ma in realtà ciò significa solo un nucleo in un momento (questo è ovvio), ma ciò non significa che durante la vita del processo esso sarà limitato a un nucleo (ciò che ho pensato prima). Ma sì, comunque, voglio sapere che quando uso il modulo cluster o avvio child_processes con Node, se stanno facendo il pieno usando le risorse (core) su una macchina. –

+1

Quindi dovresti essere in grado di testarlo in qualche modo automatico, caricando su entrambi i carichi artificiali, poi vedendo programmaticamente il loro uso combinato della cpu, ma a me sembra inutile --- dal momento che se sono indipendenti una volta, saranno in esecuzioni successive. In realtà, quello che potrebbe semplicemente fare il trucco è confrontare gli ID dei processi poiché sono abbastanza sicuro che se differiscono, funzioneranno in modo indipendente (anche se in teoria potrebbero ancora usare il blocco per non essere mai in grado di ottenere oltre il 100% della CPU). Si noti che l'opposto non è vero: se hanno lo stesso pid, potrebbero essere ancora thread diversi e in grado di eseguire due core – Claude

+2

Btw. Anche se scopri come interrogare il core su cui gira un thread, sarà impossibile garantire che entrambi i programmi lo facciano nello stesso tick del clock, quindi non ti dirà ancora nulla --- potrebbero aver cambiato core più volte tra le due chiamate nei due programmi. – Claude

3

Prova questa https://www.npmjs.com/package/nodeaffinity

Questo funziona per sistema operativo basato su Windows e Linux, tranne OSX.

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)); 
Problemi correlati