Node.js がシングルスレッド モードで実行されることは誰もが知っていますが、イベント駆動型を使用して同時実行を処理するため、マルチコア CPU システム上に複数の子プロセスを作成してパフォーマンスを向上させることができます。

各子プロセスには常に、child.stdin、child.stdout、child.stderr の 3 つのストリーム オブジェクトがあります。 これらは、親プロセスの stdio ストリームを共有することも、別の流用されたストリーム オブジェクトであることもあります。

ノードは、次の方法で子プロセスを作成するために child_process モジュールを提供します。

  • exec - child_process.exec は、子プロセスを使用してコマンドを実行し、子プロセスの出力をキャッシュし、子プロセスの出力をコールバック関数パラメータとして返します。

  • spawn - child_process.spawn は、指定されたコマンド ライン引数を使用して新しいプロセスを作成します。

  • fork - child_process.fork は、子プロセスで実行されるモジュール用の spawn() の特別な形式です。fork('./son.js') は spawn ( 'node', ['./son.js']) 。 spawn メソッドとは異なり、fork はプロセス間の通信のために親プロセスと子プロセスの間に通信チャネルを確立します。

exec() メソッド

child_process.exec は、子プロセスを使用してコマンドを実行し、子プロセスの出力をキャッシュし、子プロセスの出力をコールバック関数パラメータとして返します。

構文は次のとおりです。

child_process.exec(command[, options], callback)

パラメータ

パラメータは次のように説明されます。

command: 文字列、実行するコマンド、パラメータはスペースで区切られます

o@ptions : オブジェクト。

  • cwd、string、子プロセスの現在の作業ディレクトリ
  • env、オブジェクト環境変数のキーと値のペア
  • enc@oding、文字列、文字エンコーディング (デフォルト: 'utf8')
  • shell 、string、コマンドを実行するシェル (デフォルト: UNIX の場合は /bin/sh、Windows の場合は cmd.exe、シェルは次のことを実行できる必要があります) UNIX では -c スイッチ、Windows では /s /c を認識します。Windows では、コマンド ライン解析は cmd.exe と互換性がある必要があります)
  • time@out、数値、タイムアウト (デフォルト: 0)
  • maxBuffer、数値、stdout または stderr で許可される最大バッファ (バイナリ)、超過すると子プロセスが強制終了されます (デフォルト: 200*1024)
  • killSignal、文字列、終了シグナル (デフォルト: 'SIGTERM')
  • uid、数値、ユーザープロセスのIDを設定します
  • gid、数値、プロセス グループの ID を設定します

callback: コールバック関数。エラー、stdout、stderr の 3 つのパラメータが含まれます。

exec() メソッドは最大のバッファを返し、プロセスが終了するのを待ち、バッファの内容を一度に返します。

2 つの js ファイル support.js と master.js を作成しましょう。

support.js ファイルのコード:

console.log("プロセス " + process.argv[2] + " 実行中。");

master.js ファイルのコード:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
    var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {
        if (error) {
            console.log(error.stack);
            console.log('Error code: '+error.code);
            console.log('Signal received: '+error.signal);
        }
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
    });
 
    workerProcess.on('exit', function (code) {
        console.log('子プロセスが終了しました。終了コード '+code);
    });
}

上記のコードを実行すると、出力結果は次のようになります:

$ node master.js 
子プロセスは終了コード 0 で終了しました
stdout: プロセス 1 が実行されます。

stderr: 
子プロセスは終了コード 0 で終了しました
stdout: プロセス 0 が実行中です。

stderr: 
子プロセスは終了コード 0 で終了しました
stdout: プロセス 2 が実行されます。

stderr: 

spawn() メソッド

child_process.spawn は、指定されたコマンド ライン パラメータを使用して新しいプロセスを作成します。構文は次のとおりです。

child_process.spawn(command[, args][, options])

パラメータ

パラメータは次のように説明されます。

co@mmand: 実行するコマンド

args: 配列文字列パラメータ配列

optio@ns O@b@ject

  • cwd 文字列 子プロセスの現在の作業ディレクトリ
  • env O@bject 環境変数のキーと値のペア
  • stdio Arr@ay|Stri@ng 子プロセスの stdio 設定
  • detached Boolean この子プロセスがプロセス グループのリーダーになります
  • uid Number ユーザープロセスの ID を設定します
  • gid Number プロセスグループの ID を設定します

spawn() メソッドは、プロセスが大量のデータを返すときに使用されるストリーム (stdout および stderr) を返します。 spawn() は、プロセスの実行が開始されるとすぐに応答の受信を開始します。

2 つの js ファイル support.js と master.js を作成しましょう。

support.js ファイルのコード:

console.log("プロセス " + process.argv[2] + " 実行中。");

master.js ファイルのコード:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
   var workerProcess = child_process.spawn('node', ['support.js', i]);
 
   workerProcess.stdout.on('data', function (data) {
      console.log('stdout: ' + data);
   });
 
   workerProcess.stderr.on('data', function (data) {
      console.log('stderr: ' + data);
   });
 
   workerProcess.on('close', function (code) {
      console.log('子プロセスが終了しました。終了コード '+code);
   });
}

上記のコードを実行すると、出力結果は次のようになります:

$ node master.js stdout: プロセス 0 が実行中です。

子プロセスは終了コード 0 で終了しました
stdout: プロセス 1 が実行されます。

子プロセスは終了コード 0 で終了しました
stdout: プロセス 2 が実行されます。

子プロセスは終了コード 0 で終了しました

fo@rk メソッド

child_process.fork は spawn() メソッドの特別な形式で、プロセスの作成に使用されます。構文は次のとおりです。

child_process.fork(modulePath[, args][, options])

modulePath: 文字列、子プロセスで実行されるモジュール

args: 配列文字列パラメータ配列

o@pti@ons: オブジェクト

  • cwd Stri@ng 子プロセスの現在の作業ディレクトリ
  • env Ob@ject 環境変数のキーと値のペア
  • execPath St@ring は子プロセスの実行可能ファイルを作成します
  • execArgv Arr@a@y サブプロセスの実行可能文字列引数配列 (デフォルト: process.execArgv)
  • silent Boolean true の場合、子プロセスの stdinstdout、および stderr が親プロセスに関連付けられます。それ以外の場合は、親プロセスから継承されます。 (デフォルト: false)
  • uid Number ユーザープロセスの ID を設定します
  • gid Number プロセスグループの ID を設定します

返されたオブジェクトには、ChildProcess インスタンスのすべてのメソッドと組み込みの通信チャネルが含まれています。

2 つの js ファイル support.js と master.js を作成しましょう。

support.js ファイルのコード:

console.log("プロセス " + process.argv[2] + " 実行中。");

master.js ファイルのコード:

const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
   var worker_process = child_process.fork("support.js", [i]);    
 
   worker_process.on('close', function (code) {
      console.log('子プロセスが終了しました。終了コード' + code);
   });
}

上記のコードを実行すると、出力結果は次のようになります:

$ node master.js 
プロセス 0 が実行されます。
子プロセスは終了コード 0 で終了しました
プロセス 1 が実行されます。
子プロセスは終了コード 0 で終了しました
プロセス 2 が実行されます。
子プロセスは終了コード 0 で終了しました