ノードは I/O 操作を効率的に処理するように設計されていますが、一部の種類のプログラムはこのモデルに適していないことに注意してください。たとえば、Node を使用して CPU 集中型のタスクを処理する予定の場合、イベント ループが詰まり、プログラムの応答性が低下する可能性があります。別の方法は、CPU を大量に使用するタスクを別のプロセスにオフロードして、イベント ループを解放することです。ノードを使用すると、プロセスを生成し、新しいプロセスをその親の子にすることができます。 Node では、子プロセスは親プロセスと双方向で通信でき、ある程度、親プロセスも子プロセスを監視および管理できます。
サブプロセスを使用する必要があるもう 1 つの状況は、単純に外部コマンドを実行して、Node にコマンドの戻り値を取得させたい場合です。たとえば、Node.js で直接実行できない UNIX コマンド、スクリプト、またはその他のコマンドを実行できます。
この章では、外部コマンドの実行方法、子プロセスの作成と通信、子プロセスの終了方法を説明します。重要なのは、ノード プロセスの外で一連のタスクを完了する方法を理解できるようにすることです。
外部コマンドの実行
外部シェル コマンドまたは実行可能ファイルを実行する必要がある場合は、child_process モジュールを使用して、次のようにインポートできます。
var child_process = require('child_process')
その後、モジュール内の exec 関数を使用して外部コマンドを実行できます:
var exec = child_process.exec;
exec(コマンド,コールバック);
exec の最初のパラメータは実行するシェル コマンド文字列で、2 番目のパラメータはコールバック関数です。このコールバック関数は、exec が外部コマンドの実行を終了するか、エラーが発生したときに呼び出されます。コールバック関数には、error、stdout、stderr の 3 つのパラメータがあります。次の例を参照してください:
exec('ls',function(err,stdout,stderr){
//翻訳者注: Windows を使用している場合は、dir などの Windows コマンドに変更できますが、これについては再度説明しません
});
エラーが発生した場合、最初のパラメーターは Error クラスのインスタンスになります。最初のパラメーターにエラーが含まれていない場合、2 番目のパラメーター stdout にはコマンドの標準出力が含まれます。最後のパラメータには、コマンドに関連するエラー出力が含まれます。
リスト 8-1 は、外部コマンドを実行するより複雑な例を示しています
リスト 8-1: 外部コマンドの実行 (ソース コード: Chapter8/01_external_command.js)
//child_process モジュールの exec 関数をインポートします
var exec = require('child_process').exec;
//「cat *.js | wc -l」コマンドを呼び出します
exec(‘cat *.js | wc –l ‘, function(err, stdout, stderr ){ //4行目
//コマンドが終了するか、呼び出しが失敗します
If(err){
//外部プロセスの開始に失敗しました
console.log('child_process が終了しました。エラー コードは次のとおりです: ',err.code);
return;
}
}
4 行目では、exec の最初のパラメータとして「cat *.js | wc -l」を渡します。シェルでコマンドを使用している限り、他のコマンドを試すこともできます。
次に、エラーが発生したとき、または子プロセスが終了したときに呼び出されるコールバック関数を 2 番目のパラメータとして渡します。
コールバック関数の前に、次のような構成オプションを含む 3 番目のオプションのパラメータを渡すこともできます。
var exec = require('child_process').exec; var オプション ={
タイムアウト: 1000、
killSignal: 「SIGKILL」
};
//…
});
1.cwd - 現在のディレクトリ。現在の作業ディレクトリを指定できます。
2.encoding - 子プロセスの出力コンテンツのエンコード形式。デフォルト値は「utf8」で、UTF-8 エンコードです。子プロセスの出力が utf8 ではない場合、このパラメータを使用して設定できます。サポートされているエンコード形式は次のとおりです。
ucs2
Base64
」を参照してください。 1.timeout - コマンド実行タイムアウト (ミリ秒単位)。デフォルトは 0 で、子プロセスが終了するまで制限なしを意味します。
2.maxBuffer - stdout ストリームと stderr ストリームによって出力できる最大バイト数を指定します。最大値に達すると、子プロセスが強制終了されます。デフォルト値は 200*1024 です。
3.killSignal - タイムアウトするか、出力バッファーが最大サイズに達したときに、子プロセスに送信される終了シグナル。デフォルト値は「SIGTERM」で、子プロセスに終了シグナルを送信します。この順序立てたアプローチは通常、プロセスを終了するために使用されます。 SIGTERM シグナルを使用する場合、プロセスはシグナルを処理したり、シグナルを受信した後にシグナル プロセッサのデフォルトの動作をオーバーライドしたりできます。ターゲット プロセスで必要な場合は、他のシグナル (SIGUSR1 など) を同時にターゲット プロセスに渡すことができます。 SIGKILL シグナルの送信を選択することもできます。このシグナルはオペレーティング システムによって処理され、子プロセスを即時に強制的に終了します。この場合、子プロセスのクリーンアップ操作は実行されません。
プロセスの終了をさらに制御したい場合は、後で紹介する child_process.spawn コマンドを使用できます。
1.evn - 子プロセスに渡される環境変数を指定します。デフォルトは null です。これは、子プロセスが作成される前にすべての親プロセスの環境変数を継承することを意味します。
注: killSignal オプションを使用すると、ターゲット プロセスに文字列の形式でシグナルを送信できます。シグナルは、Node 内の文字列の形式で存在します。 以下は、UNIX シグナルと対応するデフォルトの操作のリストです。
子プロセスに拡張可能な親環境変数のセットを提供することもできます。 process.env オブジェクトを直接変更すると、Node プロセス内のすべてのモジュールの環境変数が変更されるため、多くの問題が発生します。別の方法は、新しいオブジェクトを作成して process.env 内のすべてのパラメータをコピーすることです。例 8-2: を参照してください。
exec = require('child_prcess').exec;
// process.env を envCopy
にコピーします for(ev の vaName){
envCopy[varName] = env[varName];
}
//いくつかのカスタム変数を設定します
envCopy['CUSTOM ENV VAR1'] = '何らかの値'; envCopy['CUSTOM ENV VAR2'] = '他の値';
//process.env とカスタム変数を使用してコマンドを実行します
exec(‘ls –la’,{env: envCopy}, function(err,stdout,stderr){
console.log(‘stdout:’, stdout);
console.log(‘stderr:’,stderr);
}
上記の例では、環境変数を保存するために envCopy 変数を作成します。まず、Node プロセスの環境変数を process.env からコピーし、次に変更が必要ないくつかの環境変数を追加または置換し、最後に envCopy を環境として使用します。 . 変数引数が exec 関数に渡され、外部コマンドが実行されます。
環境変数はオペレーティング システムを通じてプロセス間で受け渡され、あらゆる種類の環境変数値が文字列の形式で子プロセスに届くことに注意してください。たとえば、親プロセスに環境変数として数値 123 が含まれている場合、子プロセスは文字列として「123」を受け取ります。
次の例では、同じディレクトリに 2 つのノード スクリプト (parent.js と child.js) を作成します。最初のスクリプトは 2 つ目のファイルを呼び出します。
リスト 8-3: 親プロセスが環境変数を設定する (chapter8/03_environment_number_parent.js)
var exec = require('child_process').exec;
exec('node child.js', {env: {number: 123}}, function(err, stdout, stderr) {
if (err) { エラーをスローする }
console.log('stdout:n', stdout);
console.log('stderr:n', stderr);
});
このコードをparent.jsに保存します。以下は子プロセスのソースコードであり、child.jsに保存します(例8-4を参照)。
例 8-4: 子プロセスの環境変数解析 (chapter8/04_environment_number_child.js)
var 番号 = process.env.number;
console.log(typeof(number)); // → "文字列"
数値 = parseInt(数値, 10);
console.log(typeof(number)) // → "数値"
このファイルを child.js として保存した後、このディレクトリで次のコマンドを実行できます:
$ ノード親.js
次の出力が表示されます:
sdtou:
文字列
番号
stderr:
ご覧のとおり、親プロセスは数値環境変数を渡しますが、子プロセスはそれを文字列として受け取ります (出力の 2 行目を参照) 3 行目で文字列を数値に解析します。
子プロセスの生成
ご覧のとおり、child_process.exec() 関数を使用して外部プロセスを開始し、プロセスの終了時にコールバック関数を呼び出すことができます。これは非常に簡単に使用できますが、いくつかの欠点もあります。
1. コマンドラインパラメータと環境変数を使用することに加えて、exec() は子プロセスと通信できません
2. 子プロセスの出力はキャッシュされるため、メモリ不足になる可能性があるためストリーミングできません
幸いなことに、Node の child_process モジュールを使用すると、子プロセスの開始、停止、その他の一般的な操作をより詳細に制御できます。アプリケーションで新しい子プロセスを開始できます。Node は、親プロセスと子プロセスが相互に文字列データを送受信できるようにする双方向通信チャネルを提供します。親プロセスは、子プロセスに対していくつかの管理操作を実行し、子プロセスにシグナルを送信し、子プロセスを強制的に終了することもできます。
子プロセスの作成
child_process.spawn 関数を使用して新しい子プロセスを作成できます。例 8-5 を参照してください。
例 8-5: 子プロセスを生成します。 (chapter8/05_spawning_child.js)
// child_process モジュールの spawn 関数をインポートします
var spawn = require('child_process').spawn;
// 「tail -f /var/log/system.log」コマンドを実行するための子プロセスを生成します
var child = spawn('tail', ['-f', '/var/log/system.log']);
上記のコードは、tail コマンドを実行するためのサブプロセスを生成し、パラメーターとして「-f」と「/bar/log/system.log」を受け取ります。 tail コマンドは、/var/log/system.og ファイル (存在する場合) を監視し、追加された新しいデータを標準出力ストリームに出力します。 spawn 関数は、実際のプロセスのアクセス インターフェイスをカプセル化するポインタ オブジェクトである ChildProcess オブジェクトを返します。この例では、この新しい記述子を child という変数に割り当てます。
子プロセスからのデータをリッスン
stdout 属性を含む子プロセス ハンドルは、子プロセスの標準出力 stdout をストリーム オブジェクトとして使用します。これにより、データ ブロックが利用可能になるたびに対応するコールバックが行われるように、データ イベントをこのストリーム オブジェクトにバインドできます。関数については、以下の例を参照してください:
//子プロセスの出力をコンソールに出力します
child.stdout.on('data',function(data){
console.log(‘末尾出力: ‘ データ);
});
子プロセスがデータを標準出力に出力するたびに、親プロセスに通知され、データがコンソールに出力されます。
標準出力に加えて、プロセスには別のデフォルトの出力ストリームがあります。標準エラー ストリームは、通常、エラー情報を出力するために使用されます。
この例では、/var/log/system.log ファイルが存在しない場合、末尾プロセスは次のようなメッセージを出力します: 「/var/log/system.log: そのようなファイルまたはディレクトリはありません」 、stderrストリームを監視することで、そのようなエラーが発生したときに親プロセスに通知されます。
親プロセスは次のように標準エラー ストリームをリッスンできます:
child.stderr.on('data', function(data) {
console.log('末尾のエラー出力:', data);
});
stderr 属性も、stdout と同様に読み取り専用ストリームであり、子プロセスがデータを標準エラー ストリームに出力するたびに、親プロセスに通知され、データが出力されます。
子プロセスにデータを送信します
親プロセスは、子プロセスの出力ストリームからデータを受信するだけでなく、childPoces.stdin 属性を通じて子プロセスの標準入力にデータを書き込み、子プロセスとの間でデータを送受信することもできます。
子プロセスは、 process.stdin 読み取り専用ストリームを通じて標準入力データを監視できますが、標準入力ストリームはデフォルトで一時停止状態にあるため、最初に再開する必要があることに注意してください。
例 8-6 では、次の関数を含むプログラムを作成します。
1. 1 アプリケーション: 標準入力から整数を受け取り、それらを加算し、加算結果を標準出力ストリームに出力できるシンプルなアプリケーションです。このアプリケーションは、単純なコンピューティング サービスとして、特定の作業を実行できる外部サービスとしてノード プロセスをシミュレートします。
2. 1 つのアプリケーションのクライアントをテストし、ランダムな整数を送信し、結果を出力します。ノード プロセスが子プロセスを生成し、その子プロセスに特定のタスクを実行させる方法を示すために使用されます。
以下の例 8-6 のコードを使用して、plus_one.js という名前のファイルを作成します。
例 8-6: 1 つのアプリケーション (chapter8/06_plus_one.js)
//デフォルトで一時停止されている標準入力ストリームを復元します
process.stdin.resume();
process.stdin.on('data', function(data) {
変数番号;
{
を試してください // 入力データを整数型に解析します
数値 = parseInt(data.toString(), 10);
// 1
数値 = 1;
//結果を出力
Process.stdout.write(number "n");
} キャッチ(エラー) {
Process.stderr.write(err.message "n");
}
});
上記のコードでは、stdin 標準入力ストリームからのデータを待機し、データが利用可能になると、それが整数であると仮定して整数変数に解析し、1 を加算して結果を標準出力ストリームに出力します。 。
次のコマンドでこのプログラムを実行できます:
$node plus_one.js
実行後、プログラムは入力待ちを開始します。整数を入力して Enter を押すと、画面に 1 が加算された数値が表示されます。
Ctrl+C を押すとプログラムを終了できます。
テストクライアント
次に、前の「1 つのアプリケーション」によって提供されるコンピューティング サービスを使用するためのノード プロセスを作成する必要があります。
まず、plus_one_test.js という名前のファイルを作成します。その内容を例 8-7 に示します。
例 8-7: アプリケーション 1 のテスト (chapter8/07_plus_one_test.js)
var spawn = require('child_process').spawn;
// 1つのアプリケーションを実行する子プロセスを生成
var child = spawn('node', ['plus_one.js']);
// 関数を毎秒呼び出します
setInterval(function() {
// 10.000 未満の乱数を作成します
var 番号 = Math.floor(Math.random() * 10000);
// その番号を子プロセスに送信します:
child.stdin.write(number "n");
// 子プロセスから応答を取得して出力します:
child.stdout.once('data', function(data) {
console.log('子供が 'number' に次のデータを返信しました);
});
}, 1000);
child.stderr.on('data', function(data) {
Process.stdout.write(data);
});
1 行目から 4 行目までは「1 つのアプリケーション」を実行するためのサブプロセスが開始され、setInterval 関数を使用して 1 秒に 1 回以下の操作が実行されます。
1.. 10000 未満の新しい乱数を作成します
2. この数値を文字列として子プロセス
に渡します。
3. 子プロセスが文字列
で応答するのを待ちます。
4. 一度に 1 つの数値の計算結果だけを受け取りたいため、child.stdout.on の代わりに child.stdout.once を使用する必要があります。後者を使用すると、データイベントのコールバック関数が1秒ごとに登録され、子プロセスのstdoutがデータを受信した際に登録された各コールバック関数が実行されるため、同じ計算結果が出力されることがわかります。多くの場合、この動作は明らかに間違っています。
子プロセスが終了したときに通知を受け取る
子プロセスが終了すると、exit イベントがトリガーされます。例 8-8 は、それをリッスンする方法を示しています:例 8-8: 子プロセスの終了イベントをリッスンする (chapter8/09_listen_child_exit.js)
// "ls -la" コマンドを実行するための子プロセスを生成します
var child = spawn('ls', ['-la']);
child.stdout.on('data', function(data) {
console.log('子からのデータ: ' データ);
});
// 子プロセスが終了するとき:
child.on('exit', function(code) {
console.log('子プロセスはコードで終了しました ' code);
});
例 8-9: 子プロセスの終了コードを取得する (chapter8/10_child_exit_code.js)
// 子プロセスを生成し、「ls Does_not_exist.txt」コマンドを実行します
var child = spawn('ls', ['does_not_exist.txt']);
// 子プロセスが終了するとき
child.on('exit', function(code) {
console.log('子プロセスはコードで終了しました ' code);
});
のように、対応するシグナル コードが 2 番目のパラメーターとしてコールバック関数に渡されます。
リスト 8-10: 子プロセスの終了シグナルを取得する (chapter8/11_child_exit_signal.js)
var spawn = require('child_process').spawn;
// 子プロセスを生成し、「sleep 10」コマンドを実行します
var child = spawn('sleep', ['10']);
setTimeout(function() {
child.kill();
}, 1000);
child.on('exit', function(code, signal) {
If (コード) {
console.log('子プロセスはコードで終了しました ' code);
} else if (シグナル) {
console.log('シグナルのため子プロセスが終了しました ' シグナル);
}
});
この例では、子プロセスが 10 秒間のスリープ操作を実行するために開始されますが、10 秒前に SIGKILL シグナルが子プロセスに送信され、次の出力が得られます。
シグナル SIGTERM
により子プロセスが終了しました
シグナルを送信してプロセスを強制終了
このパートでは、シグナルを使用して子プロセスを管理する方法を学びます。シグナルは、親プロセスが子プロセスと通信したり、子プロセスを強制終了したりするための簡単な方法です。
異なるシグナル コードは異なる意味を表します。シグナルは数多くありますが、最も一般的なもののいくつかはプロセスを強制終了するために使用されます。プロセスが処理方法を知らないシグナルを受信した場合、プログラムは異常中断されます。一部の信号は子プロセスによって処理されますが、その他の信号はオペレーティング システムによってのみ処理されます。
通常、child.kill メソッドを使用して子プロセスにシグナルを送信できます。デフォルトでは SIGTERM シグナルが送信されます。
var child = spawn('sleep', ['10']);
setTimeout(function() {
child.kill();
}, 1000);
console.log('SIGUSR2 シグナルを受信しました');
});
概要
この章では、child_process.exec メソッドを使用して外部コマンドを実行する方法を学習しました。このメソッドはコマンド ライン パラメーターを使用せず、環境変数を定義することでパラメーターを子プロセスに渡します。child_process.spawn メソッドを呼び出して子プロセスを生成することで外部コマンドを呼び出す方法も学習しました。この方法では、入力ストリームと出力ストリームを使用して子プロセスと通信したり、シグナルを使用して子プロセスと通信したりできます。子プロセスを強制終了します。

Vercel是什么?本篇文章带大家了解一下Vercel,并介绍一下在Vercel中部署 Node 服务的方法,希望对大家有所帮助!

gm是基于node.js的图片处理插件,它封装了图片处理工具GraphicsMagick(GM)和ImageMagick(IM),可使用spawn的方式调用。gm插件不是node默认安装的,需执行“npm install gm -S”进行安装才可使用。

本篇文章带大家详解package.json和package-lock.json文件,希望对大家有所帮助!

本篇文章给大家分享一个Nodejs web框架:Fastify,简单介绍一下Fastify支持的特性、Fastify支持的插件以及Fastify的使用方法,希望对大家有所帮助!

如何用pkg打包nodejs可执行文件?下面本篇文章给大家介绍一下使用pkg将Node.js项目打包为可执行文件的方法,希望对大家有所帮助!

node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!

本篇文章给大家分享一个Node实战,介绍一下使用Node.js和adb怎么开发一个手机备份小工具,希望对大家有所帮助!

先介绍node.js的安装,再介绍使用node.js构建一个简单的web服务器,最后通过一个简单的示例,演示网页与服务器之间的数据交互的实现。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ホットトピック



