目次
プロセス: プロセス モジュール
コマンドパラメータをどのように処理するか?
exit イベントでは、同期操作のみを実行できます。 「exit」イベント リスナーを呼び出した後、Node.js プロセスはすぐに終了し、イベント ループ内でキューに残っている他の作業はすべて破棄されます。
深入理解 process.nextTick
子进程:child_process模块
创建子进程
父子进程通信
独立子进程
进程管道
ホームページ ウェブフロントエンド jsチュートリアル Node のプロセスとサブプロセスについて説明する記事

Node のプロセスとサブプロセスについて説明する記事

Oct 12, 2022 pm 07:31 PM
nodejs node.js node

この記事では、Node のプロセスとサブプロセスについて詳しく説明します。皆様のお役に立てれば幸いです。

Node のプロセスとサブプロセスについて説明する記事

プロセス: プロセス モジュール

プロセス モジュールは、開発者が現在のプロセスと対話するために、nodejs によって提供されるツールです。実用的な API が多数あります。ドキュメントから始めて、Leopard を垣間見て、プロセス モジュールをさらに理解して学習してください:

  • コマンド パラメーターを処理するにはどうすればよいですか?
  • 作業ディレクトリをどう扱うか?
  • 例外を処理するにはどうすればよいですか?
  • プロセスの終了を処理するにはどうすればよいですか?
  • process の標準ストリーム オブジェクト
  • process.nextTick の詳細な理解

[関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル ]

コマンドパラメータをどのように処理するか?

コマンド ライン パラメーターは 2 つの側面を参照します:

  • ノードに渡されるパラメーター。たとえば、node --harmony script.js --version--harmony はノード
  • プロセスに渡されるパラメータです。たとえば、node script.js --version --help では、--version --help はプロセス

彼らに渡されるパラメータです。 ##process.argvprocess.execArgv をそれぞれ pass# して取得します。

作業ディレクトリをどう扱うか?

現在の作業ディレクトリは、

process.cwd() を通じて取得できます。

現在の作業ディレクトリは

process.chdir(directory) を通じて切り替えることができますが、失敗すると例外がスローされます。実践例は次のとおりです:

function safeChdir(dir) {
    try {
        process.chdir(dir);
        return true;
    } catch (error) {
        return false;
    }
}
ログイン後にコピー

例外を処理するにはどうすればよいですか?

uncaughtException イベント

Nodejs は try-catch を通じて例外をキャッチできます。例外がキャッチされない場合、例外は常にイベント ループの下から湧き上がってきます。イベント ループに発生する例外が処理されない場合、現在のプロセスが異常終了します。

ドキュメントによると、プロセスの uncaughtException イベントをリッスンすることで、キャッチされなかった例外を処理できます。

process.on("uncaughtException", (err, origin) => {
    console.log(err.message);
});

const a = 1 / b;
console.log("abc"); // 不会执行
ログイン後にコピー
上記のコードでは、コンソールの出力は次のとおりです。

b は次のとおりです。定義されていません## #。エラー メッセージが捕捉され、プロセスは 0 で終了しました。開発者は、uncaughtException イベントで一部の割り当てられたリソース (ファイル記述子、ハンドルなど) をクリアすることができますが、プロセスを再起動することはお勧めできません。

unhandledRejection イベント

Promise コールバック例外が

.catch()

によってキャッチされない場合、プロセスの unhandledRejection イベントがトリガーされます: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">process.on(&quot;unhandledRejection&quot;, (err, promise) =&gt; {     console.log(err.message); }); Promise.reject(new Error(&quot;错误信息&quot;)); // 未被catch捕获的异常,交由unhandledRejection事件处理</pre><div class="contentsignin">ログイン後にコピー</div></div>

warning イベント

警告は、Node.js および Javascript のエラー処理プロセスの正式な部分ではありません。 Node.js は、アプリケーションのパフォーマンスの問題、欠陥、セキュリティ リスクにつながる可能性のあるコーディング手法を検出すると、アラートを発行できます。

たとえば、前のコードでは、キャッチされなかった Promise コールバック例外が発生すると、警告イベントがトリガーされます。

プロセスの終了を処理するにはどうすればよいですか?

process.exit() と process.exitCode

nodejs プロセスは、process.exit() を通じて終了コードを指定し、直接終了できます。

process.exit()

を直接使用することはお勧めできません。これにより、イベント ループ内のタスクが直接処理されなくなり、データの切り捨てや損失 (stdout への書き込みなど) が発生する可能性があります。 )。

setTimeout(() => {
    console.log("我不会执行");
});

process.exit(0);
ログイン後にコピー

正しく安全な処理は、

、process.exitCode を設定し、プロセスが自然に終了できるようにすることです。

setTimeout(() => {
    console.log("我不会执行");
});

process.exitCode = 1;
ログイン後にコピー

beforeExit イベント

プロセス終了の処理に使用されるイベントは、beforeExit イベントと exit イベントです。

beforeExit イベントは、Node.js がイベント ループをクリアし、スケジュールする作業がなくなったときに発生します。たとえば、終了する前に非同期操作が必要な場合は、beforeExit イベントにそれを記述することができます。

let hasSend = false;
process.on("beforeExit", () => {
    if (hasSend) return; // 避免死循环

    setTimeout(() => {
        console.log("mock send data to serve");
        hasSend = true;
    }, 500);
});

console.log(".......");
// 输出:
// .......
// mock send data to serve
ログイン後にコピー

注: beforeExit イベント内の非同期タスクの場合、タスク キューに追加されます。このとき、タスク キューがすべてのタスクを完了した後、beforeExit イベントが再度トリガーされます。したがって、これを処理しない場合、

無限ループが発生する可能性があります。 exit() が明示的に呼び出された場合、このイベントはトリガーされません。

exit イベント

exit イベントでは、同期操作のみを実行できます。 「exit」イベント リスナーを呼び出した後、Node.js プロセスはすぐに終了し、イベント ループ内でキューに残っている他の作業はすべて破棄されます。

プロセスの標準ストリーム オブジェクト

プロセスは 3 つの標準ストリームを提供します。それらの一部は、ある時点で同期的にブロックしていることに注意してください (ドキュメントを参照)。
  • process.stderr:WriteStream 类型,console.error的底层实现,默认对应屏幕
  • process.stdout:WriteStream 类型,console.log的底层实现,默认对应屏幕
  • process.stdin:ReadStream 类型,默认对应键盘输入

下面是基于“生产者-消费者模型”的读取控制台输入并且及时输出的代码:

process.stdin.setEncoding("utf8");

process.stdin.on("readable", () => {
    let chunk;
    while ((chunk = process.stdin.read()) !== null) {
        process.stdout.write(`>>> ${chunk}`);
    }
});

process.stdin.on("end", () => {
    process.stdout.write("结束");
});
ログイン後にコピー

关于事件的含义,还是请看stream 的文档。

深入理解 process.nextTick

我第一次看到 process.nextTick 的时候是比较懵的,看文档可以知道,它的用途是:把回调函数作为微任务,放入事件循环的任务队列中。但这么做的意义是什么呢?

因为 nodejs 并不适合计算密集型的应用,一个进程就一个线程,在当下时间点上,就一个事件在执行。那么,如果我们的事件占用了很多 cpu 时间,那么之后的事件就要等待非常久。所以,nodejs 的一个编程原则是尽量缩短每一个事件的执行事件。process.nextTick 的作用就在这,将一个大的任务分解成多个小的任务。示例代码如下:

// 被拆分成2个函数执行
function BigThing() {
    doPartThing();

    process.nextTick(() => finishThing());
}
ログイン後にコピー

在事件循环中,何时执行 nextTick 注册的任务呢?请看下面的代码:

setTimeout(function() {
    console.log("第一个1秒");
    process.nextTick(function() {
        console.log("第一个1秒:nextTick");
    });
}, 1000);

setTimeout(function() {
    console.log("第2个1秒");
}, 1000);

console.log("我要输出1");

process.nextTick(function() {
    console.log("nextTick");
});

console.log("我要输出2");
ログイン後にコピー

输出的结果如下,nextTick 是早于 setTimeout:

我要输出1
我要输出2
nextTick
第一个1秒
第一个1秒:nextTick
第2个1秒
ログイン後にコピー

在浏览器端,nextTick 会退化成 setTimeout(callback, 0)。但在 nodejs 中请使用 nextTick 而不是 setTimeout,前者效率更高,并且严格来说,两者创建的事件在任务队列中顺序并不一样(请看前面的代码)。

子进程:child_process模块

掌握 nodejs 的 child_process 模块能够极大提高 nodejs 的开发能力,例如主从进程来优化 CPU 计算的问题,多进程开发等等。本文从以下几个方面介绍 child_process 模块的使用:

  • 创建子进程
  • 父子进程通信
  • 独立子进程
  • 进程管道

创建子进程

nodejs 的 child_process 模块创建子进程的方法:spawn, fork, exec, execFile。它们的关系如下:

  • fork, exec, execFile 都是通过 spawn 来实现的。
  • exec 默认会创建 shell。execFile 默认不会创建 shell,意味着不能使用 I/O 重定向、file glob,但效率更高。
  • spawn、exec、execFile 都有同步版本,可能会造成进程阻塞。

child_process.spawn()的使用:

const { spawn } = require("child_process");
// 返回ChildProcess对象,默认情况下其上的stdio不为null
const ls = spawn("ls", ["-lh"]);

ls.stdout.on("data", data => {
    console.log(`stdout: ${data}`);
});

ls.stderr.on("data", data => {
    console.error(`stderr: ${data}`);
});

ls.on("close", code => {
    console.log(`子进程退出,退出码 ${code}`);
});
ログイン後にコピー

child_process.exec()的使用:

const { exec } = require("child_process");
// 通过回调函数来操作stdio
exec("ls -lh", (err, stdout, stderr) => {
    if (err) {
        console.error(`执行的错误: ${err}`);
        return;
    }
    console.log(`stdout: ${stdout}`);
    console.error(`stderr: ${stderr}`);
});
ログイン後にコピー

父子进程通信

fork()返回的 ChildProcess 对象,监听其上的 message 事件,来接受子进程消息;调用 send 方法,来实现 IPC。

parent.js 代码如下:

const { fork } = require("child_process");
const cp = fork("./sub.js");
cp.on("message", msg => {
    console.log("父进程收到消息:", msg);
});
cp.send("我是父进程");
ログイン後にコピー

sub.js 代码如下:

process.on("message", m => {
    console.log("子进程收到消息:", m);
});

process.send("我是子进程");
ログイン後にコピー

运行后结果:

父进程收到消息: 我是子进程
子进程收到消息: 我是父进程
ログイン後にコピー

独立子进程

在正常情况下,父进程一定会等待子进程退出后,才退出。如果想让父进程先退出,不受到子进程的影响,那么应该:

  • 调用 ChildProcess 对象上的unref()
  • options.detached 设置为 true
  • 子进程的 stdio 不能是连接到父进程

main.js 代码如下:

const { spawn } = require("child_process");
const subprocess = spawn(process.argv0, ["sub.js"], {
    detached: true,
    stdio: "ignore"
});

subprocess.unref();
ログイン後にコピー

sub.js 代码如下:

setInterval(() => {}, 1000);
ログイン後にコピー

进程管道

options.stdio 选项用于配置在父进程和子进程之间建立的管道。 默认情况下,子进程的 stdin、 stdout 和 stderr 会被重定向到 ChildProcess 对象上相应的 subprocess.stdin、subprocess.stdout 和 subprocess.stderr 流。 这意味着可以通过监听其上的 data事件,在父进程中获取子进程的 I/O 。

可以用来实现“重定向”:

const fs = require("fs");
const child_process = require("child_process");

const subprocess = child_process.spawn("ls", {
    stdio: [
        0, // 使用父进程的 stdin 用于子进程。
        "pipe", // 把子进程的 stdout 通过管道传到父进程 。
        fs.openSync("err.out", "w") // 把子进程的 stderr 定向到一个文件。
    ]
});
ログイン後にコピー

也可以用来实现"管道运算符":

const { spawn } = require("child_process");

const ps = spawn("ps", ["ax"]);
const grep = spawn("grep", ["ssh"]);

ps.stdout.on("data", data => {
    grep.stdin.write(data);
});

ps.stderr.on("data", err => {
    console.error(`ps stderr: ${err}`);
});

ps.on("close", code => {
    if (code !== 0) {
        console.log(`ps 进程退出,退出码 ${code}`);
    }
    grep.stdin.end();
});

grep.stdout.on("data", data => {
    console.log(data.toString());
});

grep.stderr.on("data", data => {
    console.error(`grep stderr: ${data}`);
});

grep.on("close", code => {
    if (code !== 0) {
        console.log(`grep 进程退出,退出码 ${code}`);
    }
});
ログイン後にコピー

更多node相关知识,请访问:nodejs 教程

以上がNode のプロセスとサブプロセスについて説明する記事の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Nodejsとvuejsの違い Nodejsとvuejsの違い Apr 21, 2024 am 04:17 AM

Node.js はサーバー側の JavaScript ランタイムであり、Vue.js は対話型ユーザー インターフェイスを作成するためのクライアント側の JavaScript フレームワークです。 Node.js はバックエンド サービス API 開発やデータ処理などのサーバー側開発に使用され、Vue.js はシングルページ アプリケーションや応答性の高いユーザー インターフェイスなどのクライアント側開発に使用されます。

Nodejs はバックエンド フレームワークですか? Nodejs はバックエンド フレームワークですか? Apr 21, 2024 am 05:09 AM

Node.js は、高いパフォーマンス、スケーラビリティ、クロスプラットフォーム サポート、豊富なエコシステム、開発の容易さなどの機能を備えているため、バックエンド フレームワークとして使用できます。

Nodejsをmysqlデータベースに接続する方法 Nodejsをmysqlデータベースに接続する方法 Apr 21, 2024 am 06:13 AM

MySQL データベースに接続するには、次の手順に従う必要があります。 mysql2 ドライバーをインストールします。 mysql2.createConnection() を使用して、ホスト アドレス、ポート、ユーザー名、パスワード、データベース名を含む接続オブジェクトを作成します。 connection.query() を使用してクエリを実行します。最後に connection.end() を使用して接続を終了します。

Nodejs インストール ディレクトリ内の npm ファイルと npm.cmd ファイルの違いは何ですか? Nodejs インストール ディレクトリ内の npm ファイルと npm.cmd ファイルの違いは何ですか? Apr 21, 2024 am 05:18 AM

Node.js インストール ディレクトリには、npm と npm.cmd という 2 つの npm 関連ファイルがあります。違いは次のとおりです。拡張子が異なります。npm は実行可能ファイルで、npm.cmd はコマンド ウィンドウのショートカットです。 Windows ユーザー: npm.cmd はコマンド プロンプトから使用できますが、npm はコマンド ラインからのみ実行できます。互換性: npm.cmd は Windows システムに固有ですが、npm はクロスプラットフォームで使用できます。使用上の推奨事項: Windows ユーザーは npm.cmd を使用し、他のオペレーティング システムは npm を使用します。

Nodejsのグローバル変数とは何ですか Nodejsのグローバル変数とは何ですか Apr 21, 2024 am 04:54 AM

Node.js には次のグローバル変数が存在します。 グローバル オブジェクト: グローバル コア モジュール: プロセス、コンソール、require ランタイム環境変数: __dirname、__filename、__line、__column 定数: unknown、null、NaN、Infinity、-Infinity

NodejsとJavaの間に大きな違いはありますか? NodejsとJavaの間に大きな違いはありますか? Apr 21, 2024 am 06:12 AM

Node.js と Java の主な違いは、設計と機能です。 イベント駆動型とスレッド駆動型: Node.js はイベント駆動型で、Java はスレッド駆動型です。シングルスレッドとマルチスレッド: Node.js はシングルスレッドのイベント ループを使用し、Java はマルチスレッド アーキテクチャを使用します。ランタイム環境: Node.js は V8 JavaScript エンジン上で実行され、Java は JVM 上で実行されます。構文: Node.js は JavaScript 構文を使用し、Java は Java 構文を使用します。目的: Node.js は I/O 集中型のタスクに適しており、Java は大規模なエンタープライズ アプリケーションに適しています。

Nodejs はバックエンド開発言語ですか? Nodejs はバックエンド開発言語ですか? Apr 21, 2024 am 05:09 AM

はい、Node.js はバックエンド開発言語です。これは、サーバー側のビジネス ロジックの処理、データベース接続の管理、API の提供などのバックエンド開発に使用されます。

NodejsとJavaのどちらを選択しますか? NodejsとJavaのどちらを選択しますか? Apr 21, 2024 am 04:40 AM

Web 開発において Node.js と Java にはそれぞれ長所と短所があり、どちらを選択するかはプロジェクトの要件によって異なります。 Node.js はリアルタイム アプリケーション、迅速な開発、マイクロサービス アーキテクチャに優れており、Java はエンタープライズ グレードのサポート、パフォーマンス、セキュリティに優れています。

See all articles