この記事では主に Node.js のサブプロセスとアプリケーション シナリオについての簡単な説明を紹介し、参考として提供します。
背景
ons (Alibaba Cloud RocketMQ パッケージ) は C++ に基づいてカプセル化されているため、単一プロセスでの複数のプロデューサーとコンシューマーのインスタンス化をサポートしていません。この問題を解決するために、Node.js の子プロセスが使用されます。
使用中に遭遇する落とし穴
リリース: プロセス管理がメインプロセスを閉じた後、サブプロセスはオペレーティングシステムプロセスになります (pid は 1)
いくつかの解決策
サブプロセスを独立したものとして扱う 実行中のプロセス、pidを記録し、公開時にプロセスを管理し、メインプロセスを閉じると同時にサブプロセスも閉じます
メインプロセスはシャットダウンイベントをリッスンし、それ自体に属するサブプロセスを積極的に閉じます
の種類サブプロセス
spawn: コマンドを実行
exec: コマンドを実行(新しいシェル)
execFile: ファイルを実行
fork: ファイルを実行
子プロセスの共通イベント
exit
close
error
message
closeは、データフローが閉じられるときにトリガーされるイベントであり、exitは、次のときにトリガーされるイベントです。子プロセスが終了します。複数の子プロセスが同じデータ ストリームを共有できるため、現時点では他の子プロセスがデータ ストリームを使用しているため、子プロセスの終了時に close イベントが必ずしもトリガーされるとは限りません。
サブプロセスのデータフロー
stdin
stdout
stderr
メインプロセスが開始点であるため、サブプロセスのデータフローは逆方向になります従来理解されているデータ フローに、stdin: 書き込みストリーム、stdout、stderr: 読み取りストリームを適用します。
spawn
spawn(command[, args][, options])
コマンドを実行し、データ データ ストリームを通じてさまざまな実行結果を返します。
基本的な使用法
const { spawn } = require('child_process'); const child = spawn('find', [ '.', '-type', 'f' ]); child.stdout.on('data', (data) => { console.log(`child stdout:\n${data}`); }); child.stderr.on('data', (data) => { console.error(`child stderr:\n${data}`); }); child.on('exit', (code, signal) => { console.log(`child process exit with: code $[code], signal: ${signal}`); });
共通パラメータ
{ cwd: String, env: Object, stdio: Array | String, detached: Boolean, shell: Boolean, uid: Number, gid: Number }
detached 属性を true に設定すると、子プロセスが独立して実行されるように準備されます。子プロセスの特定の動作はオペレーティング システムに関連しており、Windows システムの子プロセスには独自のコンソール ウィンドウがあり、POSIX システムの子プロセスが新しいプロセス グループおよびセッション リーダーになります。
現時点では、子プロセスは完全に独立しているわけではなく、子プロセスの実行結果はメインプロセスが設定したデータストリームに表示され、メインプロセスの終了は子プロセスの動作に影響を与えます。 stdio を無視するように設定し、child.unref(); を呼び出すと、子プロセスは実際に独立して実行を開始し、メイン プロセスは独立して終了できます。
exec
exec(command[, options][, callback])
コマンドを実行し、コールバックパラメータを通じて結果を返します。コマンドが実行されない場合、結果の一部はシステムメモリにキャッシュされます。
const { exec } = require('child_process'); exec('find . -type f | wc -l', (err, stdout, stderr) => { if (err) { console.error(`exec error: ${err}`); return; } console.log(`Number of files ${stdout}`); });
両方の長所 - spawn が exec を置き換えます
exec の結果は一度返され、返される前にメモリにキャッシュされるため、実行されたシェル コマンドの出力が大きすぎる場合は、次の方法を使用してコマンドを実行しますexec は、期待どおりに作業を完了できない場合、exec の代わりに spawn を使用してシェル コマンドを実行できます。
const { spawn } = require('child_process'); const child = spawn('find . -type f | wc -l', { stdio: 'inherit', shell: true }); child.stdout.on('data', (data) => { console.log(`child stdout:\n${data}`); }); child.stderr.on('data', (data) => { console.error(`child stderr:\n${data}`); }); child.on('exit', (code, signal) => { console.log(`child process exit with: code $[code], signal: ${signal}`); });
execFile
child_process.execFile(file[, args][, options][, callback])
ファイルを実行する
exec の機能は基本的に同じですが、違いは、指定されたパスでスクリプト ファイルを実行し、シェル環境を作成する代わりに新しいプロセスを直接作成することです。スクリプトの実行は比較的軽量で効率的です。ただし、Windows システムでは、.cmd や .bat などのファイルを直接実行することはできません。つまり、代わりに execFile を使用できます。
fork
child_process.fork(modulePath[, args][, options])
Node.js ファイルを実行します
// parent.js const { fork } = require('child_process'); const child = fork('child.js'); child.on('message', (msg) => { console.log('Message from child', msg); }); child.send({ hello: 'world' });
// child.js process.on('message', (msg) => { console.log('Message from parent:', msg); }); let counter = 0; setInterval(() => { process.send({ counter: counter++ }); }, 3000);
fork は実際には特別な形式のスポーンであり、スポーン Node.js プロセスを修正し、マスタープロセスと子プロセス間の通信チャネルを確立します。子プロセスはプロセス モジュールを使用してイベントに基づいて通信できます。
サブプロセスの使用シナリオ
コンピューティング集約型システム
フロントエンド建設ツールはマルチコアCPU並列コンピューティングを使用して建設効率を向上させます
次のようなプロセス管理ツール: いくつかの機能in PM2
上記は皆さんのためにまとめたもので、今後皆さんのお役に立てれば幸いです。
関連記事:
vue.jsでのvue-fontawesomeの使い方について
Node.js 経由で MySQL 接続プールを使用する方法
以上がNode.js のサブプロセスのアプリケーション シナリオは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。