js に詳しい友人はjs 是单线程
ことを知っています。Node では、マルチプロセス シングルスレッドモデルが採用されています。 JavaScript のシングルスレッドの制限により、マルチコア サーバーでは、サーバーのパフォーマンスを最大化するために複数のプロセスを開始する必要があることがよくあります。
Node.js プロセス クラスターを使用すると、複数の Node.js インスタンスを実行でき、アプリケーション スレッド間でワークロードを分散できます。 プロセスの分離が必要ない場合は、代わりにworker_threads
モジュールを使用します。これにより、単一の Node.js インスタンス内で複数のアプリケーション スレッドを実行できるようになります。
ノードはバージョン V0.8 以降にクラスター モジュールを導入し、一个主进程(master) 管理多个子进程(worker) 的方式实现集群
。
クラスター モジュールを使用すると、サーバー ポートを共有する子プロセスを簡単に作成できます。
クラスターの最下層は child_process モジュールで、通常のメッセージの送信に加えて、基礎となるオブジェクト
TCP
、UDP
なども送信できます。cluster
モジュールは、child_process
モジュールとnet
モジュールを組み合わせたアプリケーションです。クラスターが開始すると、TCP サーバーが内部で開始され、TCP サーバー ソケットのファイル記述子が作業プロセスに送信されます。
cluster
モジュール アプリケーションでは、一个主进程只能管理一组工作进程
。その動作モードはchild_process
モジュールほど柔軟ではありませんが、より安定しています。
const cluster = require('cluster') および複雑な
.isMaster
メイン プロセスを識別し、Node<16.isPrimary は.isPrimary
、Node>16.isWorker は.isWorker
.worker
。 [子プロセス内の] プロセス オブジェクトへの参照.workers
、 id
フィールドをキーとして、アクティブなワーカー プロセス オブジェクトのハッシュを保存します。 これにより、すべてのワーカー プロセスを簡単にループできるようになります。 メインプロセスでのみ使用できます。 cluster.wokers[id] === worker
[メインプロセス内].settings
読み取り専用のクラスター構成項目です。 .setupPrimary() または .fork() メソッドを呼び出した後、この設定オブジェクトにはデフォルト値を含む設定が含まれます。以前は空のオブジェクトでした。このオブジェクトは手動で変更または設定しないでください。cluster.settings
構成項目の詳細:- `execArgv` <string[]>Node.js 実行可能ファイルに渡される文字列パラメーターのリスト。 **デフォルト:** `process.execArgv`。 - `exec` <文字列> ワーカー プロセス ファイルへのファイル パス。 **デフォルト:** `process.argv[1]`。 - `args` <string[]> ワーカー プロセスに渡される文字列引数。 **デフォルト:** `process.argv.slice(2)`。 - `cwd` <string>ワーカー プロセスの現在の作業ディレクトリ。 **デフォルト:** `未定義` (親プロセスから継承)。 - `serialization` <string>プロセス間でメッセージを送信するために使用されるシリアル化タイプを指定します。 可能な値は「json」と「advanced」です。 **デフォルト:** `false`。 - `silent` <boolean>親プロセスの標準入出力に出力を送信するかどうか。 **デフォルト:** `false`。 - `stdio` <array>産卵プロセスの標準入力と出力を構成します。 クラスター モジュールは IPC に依存して実行されるため、この設定には `'ipc'` エントリが含まれている必要があります。 このオプションを指定すると、「silent」がオーバーライドされます。 - `uid` <number>プロセスのユーザーIDを設定します。 - `gid` <number>プロセスのグループIDを設定します。 - `inspectPort` <number> | <Function> ワーカー プロセスのインスペクタ ポートを設定します。 これは、数値、またはパラメーターを受け取らず数値を返す関数です。 デフォルトでは、各ワーカー プロセスには独自のポートがあり、メイン プロセスの「process.debugPort」から始まり増加していきます。 - `windowsHide` <boolean> Windows システムで通常作成される、生成されたプロセス コンソール ウィンドウを非表示にします。 **デフォルト:** `false`。
.fork([env])
新しいワーカー プロセスを [メイン プロセス内で] 生成します。.setupPrimary([settings])
Node>16.setupMaster([settings])
は、デフォルトの 'fork' 動作を変更するために使用されます。使用後、設定はcluster.settings
に表示されます。設定の変更は、まだ実行されていない.fork()
への将来の呼び出しにのみ影響します。上記のデフォルト値は、最初の呼び出しにのみ適用されます。ノードは 16 未満です [メイン プロセス内].disconnect([callback])
すべてのワーカー プロセスが切断してハンドルを閉じるときに呼び出されます [メイン プロセス内]クラスターをより安定して堅牢にするために、 cluster
モジュールも
'message'
多くのイベント:「メッセージ」イベントを公開します
。'exit'
イベントでは、ワーカープロセスが死ぬと、クラスターモジュールが'exit'
イベントをトリガーします。cluster.on('exit', (ワーカー、コード、シグナル) => { console.log( 'worker%d deater(%s)。再起動...'、 ワーカー.プロセス.pid、シグナルコード || クラスター.フォーク();'listening' イベント
、
'listening'
プロセスからlisten()
を呼び出した後、サーバー上で'listening'
イベントがトリガーされると、メイン プロセスのcluster
も'listening'
イベントをトリガーします。cluster.on('listening', (ワーカー, アドレス) => { コンソール.log( `ワーカーは ${address.address}:${address.port} に接続されました`); });
'fork'
イベント。新しいワーカー プロセスが生成されると、クラスター モジュールは'fork'
イベントをトリガーします。クラスタ.on('フォーク', (ワーカー) => { timeouts[worker.id] = setTimeout(errorMsg, 2000); });
.setupPrimary()
が呼び出されるたびにトリガーされる'setup'
イベント。disconnect
イベントは、ワーカー プロセスの IPC チャネルが切断された後にトリガーされます。 労働者のプロセスが正常に終了する場合、殺害されるか、クラスターを手動で切断した場合( 'disconnect'、(worker)=> { console.log(`ワーカー #${worker.id} が切断されました`); });
Worker
オブジェクトには、ワーカープロセスのすべての公開情報と方法が含まれています。 主なプロセスでは、 cluster.workers
を使用して取得できます。 ワーカー プロセスでは、 cluster.worker
使用して取得できます。
.id
プロセスの識別。各新しいワーカー プロセスには独自の ID が与えられます。この ID はid
に格納されます。ワーカー プロセスが生きている場合、これは、 cluster.workers
内でワーカー プロセスのインデックスを作成するキーになります。.process
すべてのワーカー プロセスはchild_process.fork()
を使用して作成され、この関数によって返されるオブジェクトは.process
として保存されます。 ワーカープロセスでは、グローバルprocess
が保存されます。.send(message[, sendHandle[, options]][, callback])
ワーカープロセスまたはメインプロセスにメッセージを送信し、ハンドルを使用することを選択できます。主なプロセスでは、特定のワーカープロセスにメッセージを送信します。 ChildProcess.send()
と同じです。ワーカープロセスでは、これによりメインプロセスにメッセージが送信されます。 process.send()
と同じです。.destroy()
.kill([signal])
この関数は、ワーカープロセスを殺します。 kill()
関数は、優雅な切断を待たずにWorkerプロセスを殺します。Worker.process.kill worker.process.kill()
と同じ動作をします。下位互換性を確保するために、このメソッドはworker.destroy()
のエイリアスとして使用されます。.disconnect([callback])
がワーカー プロセスに送信されると、ワーカー プロセスは独自の.disconnect()
を呼び出します。これにより、すべてのサーバーがシャットダウンされ、それらのサーバーで'close'
イベントを待機してから、IPC チャネルが切断されます。.isConnect()
この関数は、ワーカー プロセスが IPC チャネルを通じてメイン プロセスに接続されている場合はtrue
を返し、それ以外の場合はfalse
を返します。 ワーカープロセスは、作成後のマスタープロセスに接続します。.isDead()
この関数は、ワーカープロセスが終了した場合にtrue
を返します(信号の出口または受領により)。 それ以外の場合は、 false
を返します。クラスターをより安定して堅牢にするために、 cluster
モジュールは多くのイベント (
'message'
イベント) も公開します。'exit'
'exit'
当前worker工作进程
'、messagehandler);
if (cluster.isPrimary) { const ワーカー = クラスター.フォーク(); worker.on('exit', (コード, シグナル) => { if (信号) { console.log( `労働者は信号で殺されました:$ {信号}`); } else if (コード !== 0) { console.log( `ワーカーはエラーコードで終了しました:$ {code}`); } それ以外 { console.log('ワーカーの成功!'); } }); }
'listening'
イベント、ワーカープロセスからlisten()
を呼び出して、現在の労働者プロセスを聞きます。cluster.fork().on('listening', (アドレス) => { //ワーカープロセスは聞いています});
disconnect
れます。 労働者のプロセスが正常に終了する場合、殺されるか、クラスターを手動で切断した場合。fork()。//現在
の
ワーカーオブジェクトのに限定})
.send()
(a.sendはcluster模块
メッセージを送信することを意味します)メッセージを送信し、これEventEmitter
収集するためにmessage
を収集します。また、公式Webサイトの単純なインタープロセス通信
child.send()
child.on('message')
process.send()
process.on('message')
# クラスター.isMaster #cluster.fork() #Cluster.Workers #cluster.workers [id] .on( 'message'、messagehandler); # クラスター.ワーカー[id].send(); # process.on('メッセージ', messageHandler); # プロセス.send(); const クラスター = require('cluster'); const http = require('http'); # メイン処理 if (cluster.isMaster) { // http リクエストを追跡する console.log(`プライマリ ${process.pid} が実行中です`); numreqs = 0とします。 //リクエストをカウントします 関数 messageHandler(msg) { if (msg.cmd && msg.cmd === 'notifyRequest') { numReqs += 1; } } //ワーカーを起動し、NotifyRequestを含むメッセージを聞きます //マルチプロセスを開始(CPUコアの数) // ワーカープロセスを生成します。 const numcpus = require( 'os')。cpus()。length; for(i = 0; i <numcpus; i ++){ コンソール.ログ(i) クラスター.フォーク(); } //クラスターワーカーのメインプロセスは、(cluster.workersのconst id)の子プロセスと通信します{ // *** Child Processes Cluster.Workers [id] .on( 'message'、messagehandler)からイベントを聞く; // *** cluster.workers [id] .send({{to the Child Process タイプ:「MasterToworker」、 From:「マスター」、 データ: { 番号:math.floor(math.random() * 50) } }); } cluster.on( 'exit'、(worker、code、signal)=> { console.log( `worker $ {worker.process.pid} died`); }); } それ以外 { #子プロセス//ワーカープロセスは任意のTCP接続を共有できます//この例では、HTTPサーバー//ワーカープロセスがHTTPサーバーを持っています。 http.Server((req, res) => { res.writeHead(200); res.End( 'Hello World n'); //******! ! ! !リクエストについてマスターに通知してください! ! ! ! ! ! ******* // ****** process.send({cmd: 'notifyRequest'})を送信します。 // ****** process.on( 'message'、function(message)を聞く{ // xxxxxxx }) }).listen(8000); console.log( `worker $ {process.pid} startion`); }
通信の処理には、メッセージの合格のみが含まれ、実際にはオブジェクトを転送しません。
メッセージを送信する前に、このメッセージはJSON.stringify
send()
シリアルされますIPCチャネルを介して送信されます。これらはすべてJSON.parse
列です。
コードにapp.listen(port)
があります。複数のプロセスが同じポートを聴くことができますか?
これは、メインプロセスが send() メソッドを通じてメインプロセスに属するサービスオブジェクトのハンドルを複数のサブプロセスに送信するため、各サブプロセスはハンドルを復元した後、同じサービスオブジェクトを取得することになります。ネットワークがサーバーにリクエストを送信すると、プロセス サービスがプリエンプティブになるため、同じポートでリッスンしても例外は発生しません。
# master.js const fork = require('child_process').fork; const cpus = require('os').cpus(); for (let i=0; i<cpus.length; i++) { const worker = fork( 'worker.js'); console.log( 'workerプロセス作成、pid:%s ppid:%s'、worker.pid、process.pid); }
#worker.js const http = require( 'http'); http.createserver((req、res)=> { res.End( '私は労働者です、pid:' + process.pid + '、ppid:' + process.ppid); })。(3000);
上記のコードの例では、コンソールが
node master.js
ポート3000を聴くことができ、残りはError: listen EADDRINUSE :::3000
スローします。
/**
发送句柄
機能をサポートしています。* http://nodejs.cn/api/child_process.html#child_process_subprocess_send_message_sendhandle_options_callback * メッセージ * sendhandle */ SubProcess.send(メッセージ、Sendhandle)
親と子のプロセスの間にIPCチャネルが確立された後、メッセージは二个参数sendHandle 就是句柄,可以是TCP套接字、TCP服务器、UDP套接字等
プロセスオブジェクトの送信方法を介して送信されます。二个参数sendHandle 就是句柄,可以是TCP套接字、TCP服务器、UDP套接字等
#マスター.js const fork = require( 'child_process')。fork; const cpus = require('os').cpus(); const サーバー = require('net').createServer(); server.listen(3000); process.title = 'node-master' for(i = 0; i <cpus.length; i ++){ const worker = fork( 'worker.js'); #ハンドルworker.send( 'server'、server)を渡します。 console.log( 'workerプロセス作成、pid:%s ppid:%s'、worker.pid、process.pid); }
// worker.js 労働者にさせてください。 process.title = 'node-worker' process.on( 'message'、function(message、sendhandle){ if(message === 'server'){ worker = sendhandle; worker.on( 'connection'、function(socket){ console.log( '私は労働者、pid:' + process.pid + '、ppid:' + process.ppid) }); } });
コンソールがnode master.js
を実行することを確認します
cluster
理解すると、子どものプロセスがcluster.fork()
を介して作成されることがわかります。 Linuxでは、システムがfork
メソッドをネイティブに提供しているのに、システムのネイティブメソッドを直接使用するのではなく、ノードがcluster模块
単独で実装することを選択するのはなぜですか?主な理由は次の 2 点です。
フォーク プロセスが同じポートを監視するため、ポート占有エラーが発生します。
フォーク プロセス間の負荷分散が行われず、
cluster模块
でサンダーリング ハード現象が発生しやすくなります。最初の問題は、現在のプロセスがmaster进程
worker进程
ある場合、ポートで耳を傾け、ポートで聴かないかどうかを判断します。
2番目の質問に応答して、 cluster模块
には、 worker进程
master进程
が組み込まれたロードバランス機能があります。ラウンドロビン、スケジューリングアルゴリズムは、環境変数NODE_CLUSTER_SCHED_POLICY
を介して変更できます。
codeコードがキャッチされていない例外をスローすると、この時点でnode.jsはprocess.on('uncaughtException', handler)
を提供します。
プロセスがcontしていない例外に遭遇する場合、現時点ではすでに不確実な状態にあります。
+--------++---------+ | +--------++----+----+ | + -----------------+ | | | | <-------+ | | | ---+ - + | + -------------------------> + ------------------------------------------------------------------------------- - > | | | +---------------------> | | | 死ぬ| | | |
|
|
現在のプロセスは直接退場し、マスターはすぐに新しい労働者を分岐します。
モジュールは、执行cmd命令的能力
である子プロセスを導き出す機能を提供します。 デフォルトでは、 stdin、 stdout 和stderr 的管道会在父Node.js 进程和衍生的子进程之间建立
。 これらのパイプラインの容量は限られています (プラットフォーム固有)。 STDOUTへの書き込み時に子のプロセスがこの制限を超え、出力がキャプチャされない場合、子プロセスがブロックされ、パイプバッファーがより多くのデータを受け入れるのを待ちます。 これは、シェル内のパイプと同じ動作です。 出力が消費されていない場合は、{stdio: 'agnore'}オプションを使用します。
const
cp = require( 'child_process
'
)
fork(modulePath, args)
:独立したプロセスとしてノードプロセスを実行するときに使用して、計算処理とファイル記述子がノードメインプロセス(子プロセスのコピー)から分離されているように使用されます
spawn(command, args)
:いくつかの問題を処理します(file、args [、callback])が多くのサブプロセスI/OSがある場合、またはプロセスに大量の出力がある場合execFile(file, args[, callback])
外部プログラムのみを実行する必要がある場合に使用しますexecSync
exec(command, options)
execFileSync
、 spawnSync
他の3つの方法は、 spawn()
の拡張です。
ます2つの間に確立されたIPC通信チャネルを除き、親プロセス。 各プロセスには独自のメモリと独自の V8 インスタンスがあります
。
たとえば、worker.js と master.js という 2 つのファイルを
次のディレクトリに作成します。
const t = json.parse(process.argv [2]); console.error( `子プロセスt = $ {json.stringify(t)}`); process.send({hello: `son pid = $ {process.pid}お父さんプロセスpid = $ {process.ppid} hello`}); process.on( 'message'、(msg)=> { console.error( `子プロセスmsg = $ {json.stringify(msg)}`); });
#parent.js const {fork} = require( 'child_process'); for(let i = 0; i <3; i ++){ const p = fork( './ child.js'、[json.stringify({id:1、name:1})); p.on( 'message'、(msg)=> { console.log( `child msg = $ {json.stringify(msg)}`、); }); p.send({hello: `dad $ {process.pid} Process id = $ {i}`}); }
node parent.js
を通じてparent.js を起動し、 ps aux | grep worker.js
を通じてプロセス数を確認すると、理想的にはプロセス数が CPU コアの数と等しく、各プロセスが 1 つを使用していることがわかります。 CPUコア。
これは古典的なマスターワーカーモード(マスタースレーブモード)です
実際、プロセスのフォークにはコストがかかり、プロセスをコピーする目的は CPU リソースを最大限に活用することであるため、NodeJS は単一スレッドでイベント駆動型のアプローチを使用して、同時実行性が高いという問題を解決します。
適用されるシナリオ<br/>一般に時間のかかるシナリオに使用され、ファイルのダウンロードなどのノードを使用して実装されます。
フォークはマルチスレッドのダウンロードを実装できます。ファイルを複数のブロックに分割し、各プロセスが一部をダウンロードし、最後にそれらをまとめます。
const cp = require( 'child_process')を介した結果; //最初のパラメーターは、実行する実行可能ファイルの名前またはパスです。これがエコーです cp.execfile( 'echo'、['hello'、 'world']、(err、stdout、stderr)=> { if (err) { コンソール.error(err) } console.log( 'stdout:'、stdout); console.log( 'stderr:'、stderr); });
該当するシナリオ<br/> LSなどの結果に注意を払うタスク
が使用され、まだ内部的に呼び出されていますが、キャッシュには最大制限があります。
シェルconst cp = require( 'child_process')
cp.exec( `cat $ {__ dirname} /messy.txt | sort | uniq`、(err、stdout、stderr)=> { console.log(stdout); });該当するシナリオ
の低いタスクに適しています。
単一タスク
const cp = require( 'child_process')を返します。 const child = cp.spawn('echo', ['hello', 'world']); child.on( 'error'、console.error); #出力は、ストリーム、メインプロセスSTDOUTへの出力、コンソールchild.stdout.pipe(process.stdout); child.stderr.pipe(process.stderr
)
;
const path = require( 'path'); const cat = cp.spawn('cat', [path.resolve(__dirname, 'messy.txt')]); const sort = cp.spawn( 'sort'); const uniq = cp.spawn( 'uniq'); #出力はStream cat.stdout.pipe(sort.stdin); sort.stdout.pipe(uniq.stdin);uniq.stdout.pipe(
process.stdout
);
やインストールプロセスの
などの時間のかかるタスクに適しています
子プロセスは'close'
されています。このイベントは、複数のプロセスが同じstdioストリームを共有できるため、 exit
とは異なります。
パラメーター:
質問:コードは存在する必要がありますか?
(コードのコメントからではないようです)たとえば、 kill
を使用して子のプロセスを殺す場合、コードは何ですか?
パラメーター:
コード、信号、子プロセスが単独で終了する場合、 code
出口コードです。それ以外の場合はnullです。
子プロセスが信号を介して終了する場合、 signal
プロセスを終了する信号です。それ以外の場合はnullです。
2つのうち、1つはヌルであってはなりません。
注意すべきこと:
exit
イベントがトリガーされると、子プロセスのSTDIOストリームがまだ開いている可能性があります。 (シナリオ?)さらに、nodejsはSigintとSigtermの信号に耳を傾けます。つまり、これらの2つの信号を受信します。 (視覚的には、JSはデータベースの閉鎖など、現時点ではクリーンアップ作業を行うことができます。)
SIGINT
:割り込み、プログラム終了信号。通常、ユーザーがCtrl+Cを押したときに発行されます。
SIGTERM
:終了、プログラムの終了信号、この信号はブロックおよび処理でき、通常はプログラムが正常に終了することを要求するために使用されます。シェルコマンドキルは、デフォルトでこの信号を生成します。信号を終了できない場合、Sigkill(強制終了)を試みます。
次のことが発生すると、エラーがトリガーされます。エラーがトリガーされると、Exitがトリガーされる場合とトリガーできない場合があります。 (心が折れる)
送信にprocess.send()
が使用されると、メッセージがトリガーされます。
パラメーター:
message
、jsonオブジェクト、またはプリミティブ値、 sendHandle
オブジェクト(クラスターに精通した学生はこれに精通している必要があります)
: .disconnected()
を呼び出すとき、それを設定偽り。子プロセスからメッセージを受信できるか、子プロセスにメッセージを送信できるかを表します。
.disconnect() : 親プロセスと子プロセス間の IPC チャネルを閉じます。この方法が呼び出されると、 disconnect
イベントが発生します。子プロセスがノードインスタンス(child_process.fork()を介して作成された場合)の場合、 process.disconnect()
子育ての内部で積極的に呼び出して、IPCチャネルを終了することもできます。
プロセスの問題に使用され
プロセスは、Nodeのコアが
、V8のインスタンスが作成されます
の実行
单线程
ですが、JavaScriptのホスト環境は、ノードであろうとブラウザであろうと、マルチスレッドです。
JavaScriptがシングルスレッドされているのはなぜですか?
この問題は、ブラウザー環境で DOM 操作を開始する必要があります。想像してみてください。複数のスレッドが同じ DOM 上で操作する場合、DOM 操作は単一の方法でしか実行できないことになります。 DOMレンダリングの競合を避けてください。ブラウザ環境では、UIレンダリングスレッドとJS実行エンジンは相互に排他的です。
process.env.UV_THREADPOOL_SIZE = 64を手動で変更します
worker_threads
が提供されます。。 ismainthread、 ParentPort、 workerdata、 threadid、 メッシェチャンネル、 メッセージポート、 ワーカー } = require( 'worker_threads'); 関数mainthread(){ for(i = 0; i <5; i ++){ const Worker = new Worker(__ filename、{workerdata:i}); worker.on( 'exit'、code => {console.log( `main:workerはexit code $ {code}`);}で停止しました); worker.on( 'message'、msg => { console.log( `main:receive $ {msg}`); worker.postmessage(msg + 1); }); } } function workerthread(){ console.log( `worker:workerdate $ {workerdata}`); ParentPort.on( 'メッセージ'、msg => { console.log( `worker:receive $ {msg}`); })、 ParentPort.PostMessage(WorkerData); } if(ismainthread){ mainthread(); } それ以外 { workerthread(); }
const assert = require( 'assert'); const { ワーカー、 メッシェチャンネル、 メッセージポート、 ismainthread、 ParentPort } = require( 'worker_threads'); if(ismainthread){ const Worker = new Worker(__ filename); const subchannel = new MessageChannel(); worker.postmessage({hereisyourport:subchannel.port1}、[subchannel.port1]); subchannel.port2.on( 'message'、(value)=> { console.log( 'receece:'、value); }); } それ以外 { ParentPort.once( 'message'、(value)=> { assert(value.hereisyourport instance of messageport); value.heerisyourport.postmessage( '労働者がこれを送信している'); value.heerisyourport.close(); }); }
プロセスは、リソース割り当ての最小単位であり、スレッドはCPUスケジューリングの最小単位です。
(プロセス間通信)は进程间通信
です。各プロセスには、作成後に独自のアドレス空間があるため、IPCを実装する目的はプロセス間でリソースへのアクセスを共有することです。
IPCを実装するには多くの方法があります:パイプ、メッセージキュー、セマフォ、ドメインソケット、およびnode.jsはパイプを介して実装されています。
実際、親のプロセスは、最初に子供のプロセスを作成する前にこのIPCを聴き、次に子どものプロセスと環境変数を介してIPCチャネルに関連するファイル記述子を作成します。 node_channel_fd)
オブジェクトを指すファイルリソース記述子を含むために使用できるリファレンスです。
一般に、1つのポートで複数のプロセスを監視する場合は、メインプロセスエージェントの使用を検討する場合があります。
ただし、このプロキシソリューションにより、各リクエストレセプションとプロキシ転送が2つのファイル記述子を使用し、システムのファイル記述子が制限されます。
では、なぜハンドルを使用するのですか?その理由は、実際のアプリケーション シナリオでは、IPC 通信の確立に、より複雑なデータ処理シナリオが含まれる可能性があるためです。ハンドルは、 send()
メソッドの 2 番目のオプションのパラメーターとして渡すことができます。これは、リソース識別子を直接渡すことができることを意味します。トランスミッションは、上記のプロキシ転送によって引き起こされるファイル記述子の使用を回避します。
以下は、送信をサポートするハンドルタイプです:
プロセスの親プロセスが子プロセスを作成した後、親プロセスは終了しますが、1人以上の子供親プロセスに対応するプロセスはまだ生存しています。これらの子プロセスは、システムのinitプロセスによって採用され、対応するプロセスPPIDは1であり、孤児プロセスです。これは、次のコードの例で示されています。
#worker.js const http = require( 'http'); const server = http.createserver((req、res)=> { res.End( '私は労働者です、pid:' + process.pid + '、ppid:' + process.ppid); //現在のワーカープロセスを記録しますpidおよび親プロセスppid }); 労働者にさせてください。 process.on( 'message'、function(message、sendhandle){ if(message === 'server'){ worker = sendhandle; worker.on( 'connection'、function(socket){ server.emit( 'connection'、socket); }); } });
#master.js const fork = require( 'child_process')。fork; const server = require( 'net')。createServer(); server.listen(3000); const worker = fork( 'worker.js'); worker.send( 'server'、server); console.log( 'workerプロセス作成、pid:%s ppid:%s'、worker.pid、process.pid); process.exit(0); //子どものプロセスを作成した後、この時点で作成されたワーカープロセスは
テスト用の孤児プロセスコンソールになり、現在のワーカープロセスPIDおよび親プロセスPPIDが出力されます。
親プロセスはmaster.jsで終了されるため、アクティビティモニターにはワーカープロセスのみが表示されます。
もう一度確認し、コンソールコールインターフェイスを開き、ワーカープロセス5611に対応するPPIDが1(initプロセスの場合)であり、現時点では孤立したプロセスになっていることがわかります。
プロセスはバックグラウンドで実行され、端末の影響を受けません。
node.jsを開発する学生は、ターミナルnode app.js
開き、サービスプロセスを開始すると、端末を閉じると、サービスが切断されます。前台运行模式
。
Daemon Processメソッドが使用されている場合、 node app.js
を実行してこの端末でサービスプロセスを開始した後、この端末で他のことを行うこともできずに他のことを行うこともできます。
チャイルドプロセスの作成
チャイルドプロセスで新しいセッションを作成する(システム関数SetSIDを呼び出す)
CHIRDプロセスの作業ディレクトリ( "/"または "/usr/など)の変更ディレクトリを変更します。
親プロセスを終了します
options.detached
exits(SetSidメソッド)が2番目のステップ番目
const spawn = require( 'child_process')。spawn; function startdaemon(){ const daemon = spawn( 'node'、['daemon.js']、{ CWD: '/usr'、 分離した:本当、 stdio:「無視」、 }); console.log( 'デーモンプロセスは親プロセスを開始しますpid:%s、デーモンプロセスpid:%s'、process.pid、daemon.pid); daemon.unref(); } startdaemon()
daemon.js
ファイルの処理ロジックはタイマーを起動し、10秒ごとに実行します。
子プロセスの。const fs = require('fs'); const {console} = require( 'console'); //カスタムシンプルロガー const logger = new Console(fs.createwritestream( './ stdout.log')、fs.createwritestream( './ stderr.log')); setInterval(function(){ logger.log( 'daemon pid:'、process.pid、 '、ppid:'、process.ppid); }、1000 * 10);
daemonプロセスはnode.jsバージョンのソースコードアドレス
https://
q-angelo/project-trainingを実装しています
、PM2、卵クラスターなどのデーモンプロセスに対する見知らぬ人ではありませんデーモンプロセスは、プロセスの監視、作業プロセス管理とスケジューリング、ハングアップ後のプロセスの再起動など、非常に高いものです。これらは常に考えられる必要があります。
5。の作業process.cwd()
は何ですか
?たとえば、 process.chdir()
たとえば、FSを介してファイルを読み取ると、現在のプロセスが誤って設定されている場合、ディレクトリに比べて検索され
ます
正しい結果は取得されません。別のケースでは、プログラムで参照されているサードパーティモジュールも、現在のプロセスが開始されるディレクトリに基づいて検索されます。
// process.chdir( '/users/may/documents/test/')//現在のプロセスディレクトリConsole.log(process.cwd());