導入Node.js のメイン イベント ループはシングル スレッドです。Node.js 自体も、時間のかかる操作を処理するためにワーカー プールを維持しています。また、Node.js が提供する worker_threads を使用して、手動で新しいスレッドを作成し、独自のタスクを実行することもできます。 この記事では、Node.js タスク、子プロセスを実行する新しい方法を紹介します。 子プロセスlib/child_process.js は、子プロセスを作成できる child_process モジュールを提供します。 worker_threads は子スレッドを作成し、child_process は子プロセスを作成することに注意してください。 child_process モジュールでは、プロセスを同期的または非同期的に作成できます。同期作成方法は、非同期作成方法の後に Sync を追加するだけです。 作成されたプロセスは、ChildProcess クラスによって表されます。 ChildProcess の定義を見てみましょう。 インターフェイス ChildProcess は events.EventEmitter を拡張します { stdin: 書き込み可能 | null; stdout: 読み取り可能 | null; stderr: 読み取り可能 | null; 読み取り専用チャネル?: パイプ | null; 読み取り専用stdio: [ 書き込み可能 | null, // stdin 読み取り可能 | null, // stdout 読み取り可能 | null, // stderr 読み取り可能 | 書き込み可能 | null | undefined、// 追加 読み取り可能 | 書き込み可能 | null | undefined // 追加 ]; 読み取り専用で削除されました: ブール値; 読み取り専用 pid: 数値; 読み取り専用接続: ブール値; 読み取り専用終了コード: 数値 | null; 読み取り専用シグナルコード: NodeJS.Signals | null; 読み取り専用spawnargs: string[]; 読み取り専用の spawnfile: 文字列; kill(シグナル?: NodeJS.Signals | 数値): ブール値; send(message: Serializable、callback?: (error: Error | null) => void): boolean; send(message: Serializable、sendHandle?: SendHandle、callback?: (error: Error | null) => void): boolean; send(message: Serializable、sendHandle?: SendHandle、options?: MessageOptions、callback?: (error: Error | null) => void): boolean; 切断(): 無効; 参照を解除します。 ref(): void; /** * イベント.EventEmitter * 1.閉じる * 2. 切断する * 3. エラー * 4. 終了 * 5. メッセージ */ ... } ChildProcess も EventEmitter であるため、イベントを送受信できることがわかります。 ChildProcess は、close、disconnect、error、exit、message の 5 種類のイベントを受信できます。 切断イベントは、親プロセスで subprocess.disconnect() が呼び出されたとき、または子プロセスで process.disconnect() が呼び出されたときにトリガーされます。 プロセスを作成できない場合、プロセスを終了できない場合、または子プロセスにメッセージを送信できない場合に、エラー イベントがトリガーされます。 子プロセスが終了すると、終了イベントがトリガーされます。 子プロセスの stdio ストリームが閉じられると、close イベントが発行されます。 複数のプロセスが同じ stdio を共有する可能性があるため、close イベントは exit イベントとは異なることに注意してください。そのため、exit イベントを送信しても、必ずしも close イベントがトリガーされるわけではありません。 close と exit の例を見てみましょう。 const { spawn } = require('child_process'); ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('データ', (データ) => { console.log(`stdout: ${data}`); }); ls.on('close', (コード) => { console.log(`子プロセスはコード $[code] を使用してすべての stdio を閉じます`); }); ls.on('exit', (コード) => { console.log(`子プロセスはコード $[code] で終了しました`); }); 最後に、子プロセスが process.send() を使用してメッセージを送信したときにトリガーされるメッセージ イベントがあります。 ChildProcess には、stderr、stdout、stdin、stdio といったいくつかの標準ストリーム属性があります。 stderr、stdout、stdin は簡単に理解できます。それぞれ標準エラー、標準出力、標準入力です。 stdout の使用法を見てみましょう。 const { spawn } = require('child_process'); const サブプロセス = spawn('ls'); サブプロセス.stdout.on('データ', (データ) => { console.log(`データブロック ${data} を受信しました`); }); stdio は実際には stderr、stdout、stdin の集合です。 読み取り専用stdio: [ 書き込み可能 | null, // stdin 読み取り可能 | null, // stdout 読み取り可能 | null, // stderr 読み取り可能 | 書き込み可能 | null | undefined、// 追加 読み取り可能 | 書き込み可能 | null | undefined // 追加 ]; このうち、stdio[0]はstdin、stdio[1]はstdout、stdio[2]はstderrを表します。 子プロセスが stdio で作成されるときに 3 つの標準ストリームがパイプ以外に設定されている場合、stdin、stdout、および stderr は null になります。 stdio を使用した例を見てみましょう。 const assert = require('assert'); 定数 fs = require('fs'); 定数 child_process = require('child_process'); 定数サブプロセス = child_process.spawn('ls', { 標準入出力: 0, // 子プロセスに親プロセスの標準入力を使用します。 'pipe', // 子プロセスの stdout をパイプ経由で親プロセスに渡します。 fs.openSync('err.out', 'w') // 子プロセスの stderr をファイルに送信します。 ] }); assert.strictEqual(サブプロセス.stdio[0]、null); assert.strictEqual(サブプロセス.stdio[0]、サブプロセス.stdin); サブプロセス.stdout をアサートします。 assert.strictEqual(サブプロセス.stdio[1]、サブプロセス.stdout); assert.strictEqual(サブプロセス.stdio[2]、null); assert.strictEqual(サブプロセス.stdio[2]、サブプロセス.stderr); 通常、親プロセスは子プロセスへの参照カウントを維持し、子プロセスが終了した後にのみ親プロセスが終了します。 この参照は ref であり、unref メソッドが呼び出されると、親プロセスは子プロセスとは独立して終了できるようになります。 const { spawn } = require('child_process'); const サブプロセス = spawn(process.argv[0], ['child_program.js'], { 分離: true、 stdio: '無視' }); サブプロセス.unref(); 最後に、ChildProcess を通じてメッセージを送信する方法を見てみましょう。 サブプロセス.send(メッセージ[, sendHandle[, オプション]][, コールバック]) ここで、message は送信されるメッセージであり、callback はメッセージが送信された後のコールバックです。 sendHandle は特別です。TCP サーバーまたはソケット オブジェクトにすることができ、これらのハンドルを子プロセスに渡します。子プロセスは、メッセージ イベント内のコールバック関数にハンドルを渡し、子プロセスで処理できるようにします。 TCP サーバーを通過する例を見てみましょう。まず、メイン プロセスを見てみましょう。 サブプロセスは、'child_process' を要求します。'subprocess.js' をフォークします。 // サーバー オブジェクトを開き、ハンドルを送信します。 const server = require('net').createServer(); server.on('接続', (ソケット) => { socket.end('親プロセスによって処理されます'); }); server.listen(1337, () => { サブプロセス.send('server', server); }); サブプロセスをもう一度見てみましょう。 process.on('メッセージ', (m, server) => { if (m === 'サーバー') { server.on('接続', (ソケット) => { socket.end('子プロセスによって処理されました'); }); } }); 子プロセスがサーバー ハンドルを受信し、子プロセスで接続イベントをリッスンしていることがわかります。 ソケット オブジェクトを渡す例を見てみましょう。 onst { fork } = require('child_process'); 'subprocess.js' を fork します。 'subprocess.js' を fork します。 // サーバーを起動し、ソケットを子プロセスに送信します。 // 子プロセスに送信される前にソケットが読み取られないようにするには、`pauseOnConnect` を使用します。 const server = require('net').createServer({ pauseOnConnect: true }); server.on('接続', (ソケット) => { // 特別な優先度。 (ソケット.リモートアドレス === '74.125.127.100')の場合{ special.send('socket', ソケット); 戻る; } // 通常の優先度。 通常は、ソケットを送信します。 }); サーバーを listen (1337); subprocess.js の内容: process.on('メッセージ', (m, ソケット) => { if (m === 'ソケット') { if (ソケット) { // クライアントソケットが存在するかどうかを確認します。 // ソケットは、送信されてから子プロセスによって受信されるまでの間に閉じられることがあります。 socket.end(`リクエストは${process.argv[2]}の優先度を使用して処理されます`); } } }); メイン プロセスは、特別な優先度のサブプロセスと通常の優先度のサブプロセスの 2 つを作成します。 プロセスを非同期的に作成するchild_process モジュールには、プロセスを非同期に作成する 4 つの方法、つまり、child_process.spawn()、child_process.fork()、child_process.exec()、child_process.execFile() があります。 まず、各メソッドの定義を見てみましょう。 child_process.spawn(コマンド[, 引数][, オプション]) child_process.fork(モジュールパス[, 引数][, オプション]) child_process.exec(コマンド[, オプション][, コールバック]) child_process.execFile(ファイル[, 引数][, オプション][, コールバック]) このうち、child_process.spawn が基礎となり、非同期的に新しいプロセスを生成します。その他の fork、exec、execFile はすべて spawn をベースに生成されます。 Fork により新しい Node.js プロセスが生成されます。 exec と execFile は、コールバックを使用して新しいプロセスで新しいコマンドを実行します。それらの違いは、Windows 環境では、.bat ファイルまたは .cmd ファイルを実行する場合、シェル ターミナルがないと実行できないことです。現時点では、exec でのみ起動できます。 execFile は実行可能ではありません。 あるいは、spawn を使用することもできます。 Windows で spawn と exec を使用する例を見てみましょう。 // Windows のみ。 const { spawn } = require('child_process'); const bat = spawn('cmd.exe', ['/c', 'my.bat']); bat.stdout.on('データ', (データ) => { コンソールにログ出力します。 }); bat.stderr.on('データ', (データ) => { コンソールエラー(data.toString()); }); bat.on('exit', (コード) => { console.log(`サブプロセスが終了しました。終了コードは $[code]`); }); const { exec, spawn } = require('child_process'); exec('my.bat', (err, stdout, stderr) => { もし(エラー){ コンソールエラー(err); 戻る; } コンソールログ(標準出力) }); // ファイル名にスペースが含まれるスクリプト: const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true }); // または: exec('"my script.cmd" a b', (err, stdout, stderr) => { // ... }); 同期作成プロセスプロセスを同期的に作成するには、child_process.spawnSync()、child_process.execSync()、および child_process.execFileSync() を使用できます。同期メソッドは、Node.js イベント ループをブロックし、子プロセスが終了するまで他のコードの実行を中断します。 通常、一部のスクリプト タスクでは、同期作成プロセスを使用するのが一般的です。 これで、Node.js で子プロセスを作成する方法についての記事は終了です。Node.js で子プロセスを作成する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Ubuntu 上の MySQL における中国語文字化け問題の解決方法
>>: 実行後にdocker nginxにアクセスできない問題の解決策
HTML では、Web ページで使用されるエンコーディングを指定する必要があります。一般的な指定方法...
基礎トランザクションは、SQL ステートメントのグループに対するアトミック操作です。つまり、グループ...
現在、.net Core はクロスプラットフォームであり、誰もが Linux と Docker を使...
絶対 URL は、インターネット上の特定のファイルに必要なすべてのコンテンツを表すために使用されます...
[必須] ユーザーインターフェースPhotoShop/花火デザインアーティストと協力して、スケッチを...
この記事では、MySQL で 2 つのテーブルを関連付ける結合テーブルにインデックスを作成する方法を...
> MySQL 5.7 クラスタ マスターとスレーブをデプロイする (テストのみ)イメージバー...
私はmysql ERROR 1045に遭遇し、この問題に長い時間を費やしました。私はそれを自分で書き...
この記事では、Linux で PHP curl 拡張機能をインストールする方法について説明します。ご...
目次複数テーブル結合クエリ内部結合左結合右結合サブクエリ要約する複数テーブル結合クエリテーブル間の接...
(1)各HTMLタグには属性スタイルがあり、CSSとHTMLを組み合わせている。 <div s...
必要な環境をインストールする1. gccのインストールnginx をインストールするには、公式サイト...
この例では、jQuery を使用してマウス ドラッグ イメージ機能を実装します。まず、ラッパーを設定...
問題の説明:フロントエンドがデータの一部を削除したり、新しいデータを追加したりすると、バックエンドの...
MySQL のトランザクションはデフォルトで自動的にコミットされます (autocommit = 1...