検索
ホームページウェブフロントエンドjsチュートリアルNodeのプロセスとスレッドの詳細な分析

Nodeのプロセスとスレッドの詳細な分析

Dec 27, 2022 pm 07:16 PM
nodejs​プロセス

スレッドとプロセスはコンピューター オペレーティング システムの基本概念であり、プログラマーの間でよく使われる言葉です。どのように理解すればよいでしょうか? Node.js のプロセスとスレッドはどうなるでしょうか?次の記事では、Node のプロセスとスレッドについて詳しく説明します。一定の参考値があるので、困っている友達が参考になれば幸いです。

Nodeのプロセスとスレッドの詳細な分析

#1. プロセスとスレッド

1.1. プロフェッショナル テキストの定義

    プロセス (プロセス)、プロセスは、特定のデータ セット上でコンピュータ内のプログラムを実行するアクティビティです。システム内のリソース割り当てとスケジューリングの基本単位です。オペレーティング システム構造の基礎です。 process はスレッドのコンテナです。 [関連チュートリアルの推奨事項:
  • nodejs ビデオ チュートリアル プログラミング教育 ]
  • スレッド (スレッド)、スレッドはオペレーティング システムが計算スケジュールを実行できる最小単位です。 「インプロセス」に含まれるのは、プロセス内の実際の営業単位です。

1.2. 一般的な理解

上記の説明は比較的難しいため、読んでも理解できない可能性があり、理解や記憶には役立ちません。 。簡単な例を見てみましょう:

あなたが、ある宅配便サイトに勤めているとします。最初、このサイトが担当するエリアにはあまり住民が多くなく、集荷をするのはあなただけです。パッケージ。 Zhang San の家に荷物を届け、Li Si の家に荷物を取りに行った後は、物事を 1 つずつ実行する必要があります。これは

シングル スレッドと呼ばれ、すべての作業は ## の順序で実行する必要があります。 #。 その後、このエリアにはさらに多くの住民が存在し、サイトはこのエリアに複数の兄弟と 1 人のチーム リーダーを割り当てました。より多くの住民にサービスを提供できます。これは マルチスレッド
と呼ばれ、チーム リーダーです。 メイン スレッド 、そしてすべての人が スレッド です。 宅配便の現場で使用される台車などのツールは現場が提供し、一人だけでなく全員が利用できるようにすることをマルチスレッドリソース共有と呼びます。
現在、サイト カートは 1 つだけであり、全員がそれを使用する必要があります。これは 競合
と呼ばれます。これを解決するには、列に並んで待ったり、他の人が終わってから通知を待ったりするなど、さまざまな方法がありますが、これを スレッド同期 と呼びます。

Nodeのプロセスとスレッドの詳細な分析本社には多数の拠点があり、各拠点の運用モデルはほぼ同一であり、これを

マルチプロセス

と呼びます。本社を メインプロセス と呼び、各拠点を サブプロセス と呼びます。 本社と拠点間、および各拠点間ではカートが互いに独立しており、混在することができません。これを 工程間のリソース共有なし
といいます。各サイトは、パイプラインと呼ばれる電話やその他の方法を介して相互に通信できます。大規模なコンピューティング タスクの完了を容易にするために、サイト間のコラボレーションには他にも プロセス間同期 と呼ばれる手段があります。 Ruan Yifeng の

プロセスとスレッドの簡単な説明

も参照してください。

2. Node.js のプロセスとスレッド

Node.js は、シングルスレッド サービス、イベント駆動型、ノンブロッキング I/O モデル言語機能です。 , Node.js の作成は効率的かつ軽量です。利点は、頻繁なスレッド切り替えとリソースの競合を回避し、I/O 集中型の操作に優れていることです (基礎となるモジュール libuv は、マルチタスクを実行するために、マルチスレッドを介してオペレーティング システムによって提供される非同期 I/O 機能を呼び出します)。 , ただし、サーバー側の Node.js の場合、1 秒あたりに数百のリクエストを処理する必要がある可能性があり、CPU 集中型のリクエストに直面すると、シングルスレッド モードであるため、必然的にブロックが発生します。

2.1. Node.js のブロック

Koa を使用して Web サービスを単純​​に構築し、フィボナッチ数列メソッドを使用して Node.js の処理 CPU 集中型計算タスクをシミュレートします。 :

黄金分割数列としても知られるフィボナッチ数列。この数列は 3 番目の項目から始まり、各項目は前の 2 つの項目の合計に等しくなります: 0、1、1、2、 3、5、8、13、21、...

// app.js
const Koa = require('koa')
const router = require('koa-router')()
const app = new Koa()

// 用来测试是否被阻塞
router.get('/test', (ctx) => {
    ctx.body = {
        pid: process.pid,
        msg: 'Hello World'
    }
})
router.get('/fibo', (ctx) => {
    const { num = 38 } = ctx.query
    const start = Date.now()
    // 斐波那契数列
    const fibo = (n) => {
        return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1
    }
    fibo(num)

    ctx.body = {
        pid: process.pid,
        duration: Date.now() - start
    }
})

app.use(router.routes())
app.listen(9000, () => {
    console.log('Server is running on 9000')
})
実行
node app.js

サービスを開始し、Postman を使用してリクエストを送信すると、次のようになります。 38 回の計算に 617 ミリ秒かかったことがわかりました。つまり、CPU 集中型の計算タスクが実行されたため、Node.js のメイン スレッドが 600 ミリ秒以上ブロックされました。より多くのリクエストが同時に処理される場合、または計算タスクがより複雑な場合、これらのリクエスト以降のすべてのリクエストは遅延します。

Nodeのプロセスとスレッドの詳細な分析複数のリクエストの送信をシミュレートするために新しい axios.js を作成します。このとき、より複雑な計算をシミュレートするために、app.js の fibo 計算の数を 43 に変更します。タスク:

// axios.js
const axios = require('axios')

const start = Date.now()
const fn = (url) => {
    axios.get(`http://127.0.0.1:9000/${ url }`).then((res) => {
        console.log(res.data, `耗时: ${ Date.now() - start }ms`)
    })
}

fn('test')
fn('fibo?num=43')
fn('test')

可以看到,当请求需要执行 CPU 密集型的计算任务时,后续的请求都被阻塞等待,这类请求一多,服务基本就阻塞卡死了。对于这种不足,Node.js 一直在弥补。

2.2、master-worker

master-worker 模式是一种并行模式,核心思想是:系统有两个及以上的进程或线程协同工作时,master 负责接收和分配并整合任务,worker 负责处理任务。

Nodeのプロセスとスレッドの詳細な分析

2.3、多线程

线程是 CPU 调度的一个基本单位,只能同时执行一个线程的任务,同一个线程也只能被一个 CPU 调用。如果使用的是多核 CPU,那么将无法充分利用 CPU 的性能。

多线程带给我们灵活的编程方式,但是需要学习更多的 Api 知识,在编写更多代码的同时也存在着更多的风险,线程的切换和锁也会增加系统资源的开销。

worker_threads 是 Node.js 提供的一种多线程 Api。对于执行 CPU 密集型的计算任务很有用,对 I/O 密集型的操作帮助不大,因为 Node.js 内置的异步 I/O 操作比 worker_threads 更高效。worker_threads 中的 Worker,parentPort 主要用于子线程和主线程的消息交互。

将 app.js 稍微改动下,将 CPU 密集型的计算任务交给子线程计算:

// app.js
const Koa = require('koa')
const router = require('koa-router')()
const { Worker } = require('worker_threads')
const app = new Koa()

// 用来测试是否被阻塞
router.get('/test', (ctx) => {
    ctx.body = {
        pid: process.pid,
        msg: 'Hello World'
    }
})
router.get('/fibo', async (ctx) => {
    const { num = 38 } = ctx.query
    ctx.body = await asyncFibo(num)
})

const asyncFibo = (num) => {
    return new Promise((resolve, reject) => {
        // 创建 worker 线程并传递数据
        const worker = new Worker('./fibo.js', { workerData: { num } })
        // 主线程监听子线程发送的消息
        worker.on('message', resolve)
        worker.on('error', reject)
        worker.on('exit', (code) => {
            if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`))
        })
    })
}

app.use(router.routes())
app.listen(9000, () => {
    console.log('Server is running on 9000')
})

新增 fibo.js 文件,用来处理复杂计算任务:

const { workerData, parentPort } = require('worker_threads')
const { num } = workerData

const start = Date.now()
// 斐波那契数列
const fibo = (n) => {
    return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1
}
fibo(num)

parentPort.postMessage({
    pid: process.pid,
    duration: Date.now() - start
})

执行上文的 axios.js,此时将 app.js 中的 fibo 计算次数改为 43,用来模拟更复杂的计算任务:

Nodeのプロセスとスレッドの詳細な分析

可以看到,将 CPU 密集型的计算任务交给子线程处理时,主线程不再被阻塞,只需等待子线程处理完成后,主线程接收子线程返回的结果即可,其他请求不再受影响。
上述代码是演示创建 worker 线程的过程和效果,实际开发中,请使用线程池来代替上述操作,因为频繁创建线程也会有资源的开销。

线程是 CPU 调度的一个基本单位,只能同时执行一个线程的任务,同一个线程也只能被一个 CPU 调用。

我们再回味下,本小节开头提到的线程和 CPU 的描述,此时由于是新的线程,可以在其他 CPU 核心上执行,可以更充分的利用多核 CPU。

2.4、多进程

Node.js 为了能充分利用 CPU 的多核能力,提供了 cluster 模块,cluster 可以通过一个父进程管理多个子进程的方式来实现集群的功能。

  • child_process 子进程,衍生新的 Node.js 进程并使用建立的 IPC 通信通道调用指定的模块。
  • cluster 集群,可以创建共享服务器端口的子进程,工作进程使用 child_process 的 fork 方法衍生。

cluster 底层就是 child_process,master 进程做总控,启动 1 个 agent 进程和 n 个 worker 进程,agent 进程处理一些公共事务,比如日志等;worker 进程使用建立的 IPC(Inter-Process Communication)通信通道和 master 进程通信,和 master 进程共享服务端口。

Nodeのプロセスとスレッドの詳細な分析

新增 fibo-10.js,模拟发送 10 次请求:

// fibo-10.js
const axios = require('axios')

const url = `http://127.0.0.1:9000/fibo?num=38`
const start = Date.now()

for (let i = 0; i  {
        console.log(res.data, `耗时: ${ Date.now() - start }ms`)
    })
}

可以看到,只使用了一个进程,10 个请求慢慢阻塞,累计耗时 15 秒:

Nodeのプロセスとスレッドの詳細な分析

接下来,将 app.js 稍微改动下,引入 cluster 模块:

// app.js
const cluster = require('cluster')
const http = require('http')
const numCPUs = require('os').cpus().length
// const numCPUs = 10 // worker 进程的数量一般和 CPU 核心数相同
const Koa = require('koa')
const router = require('koa-router')()
const app = new Koa()

// 用来测试是否被阻塞
router.get('/test', (ctx) => {
    ctx.body = {
        pid: process.pid,
        msg: 'Hello World'
    }
})
router.get('/fibo', (ctx) => {
    const { num = 38 } = ctx.query
    const start = Date.now()
    // 斐波那契数列
    const fibo = (n) => {
        return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1
    }
    fibo(num)

    ctx.body = {
        pid: process.pid,
        duration: Date.now() - start
    }
})
app.use(router.routes())

if (cluster.isMaster) {
    console.log(`Master ${process.pid} is running`)
    
    // 衍生 worker 进程
    for (let i = 0; i  {
        console.log(`worker ${worker.process.pid} died`)
    })
} else {
    app.listen(9000)
    console.log(`Worker ${process.pid} started`)
}

执行 node app.js 启动服务,可以看到,cluster 帮我们创建了 1 个 master 进程和 4 个 worker 进程:

Nodeのプロセスとスレッドの詳細な分析

Nodeのプロセスとスレッドの詳細な分析

通过 fibo-10.js  模拟发送 10 次请求,可以看到,四个进程处理 10 个请求耗时近 9 秒:

Nodeのプロセスとスレッドの詳細な分析

10 個のワーカー プロセスが開始されたときの効果を見てみましょう:

Nodeのプロセスとスレッドの詳細な分析

所要時間はわずか 3 秒未満ですが、プロセスの数は無制限ではありません。日常の開発では、通常、ワーカー プロセスの数は CPU コアの数と同じになります。

2.5. マルチプロセスの説明

マルチプロセスを有効にすることは、完全に高い同時実行性に対処するためではなく、マルチコア CPU の使用率が不十分であるという問題を解決するためです。 Node.js。
fork メソッドを通じて親プロセスから派生した子プロセスは、親プロセスと同じリソースを持ちますが、独立しており、互いにリソースを共有しません。システム リソースには限りがあるため、プロセス数は通常、CPU コアの数に基づいて設定されます。

3. 概要

1. マルチスレッドによる CPU 集中型のコンピューティング タスクに対するソリューションのほとんどは、マルチプロセス ソリューションに置き換えることができます。 Node.js は非同期ですが、ブロックされないという意味ではありません。メイン スレッドのスムーズな流れを確保するために、メイン スレッドで CPU を集中的に使用するタスクを処理しないことが最善です;
3. 盲目的に追求しないでください高いパフォーマンスと高い同時実行性を備え、システムのニーズを満たします。ただし、プロジェクトに必要なのは効率と俊敏性であり、これは Node.js の軽量な特性でもあります。
4. Node.js には、I/O libuv の基盤となる Node.js、IPC 通信チャネルなど、記事内で言及されているものの詳細には説明されていない、または言及されていないプロセスやスレッドの概念が多数あります。プロセス間のリソースが共有されていない場合に、プロセスを保護する方法、スケジュールされたタスク、エージェント プロセスなどを処理する方法;
5. 上記のコードは、
https://github.com/liuxy0551/ で参照できます。ノードプロセススレッド

ノード関連の知識の詳細については、

nodejs チュートリアル を参照してください。

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

声明
この記事は博客园で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
JavaScriptの起源:その実装言語の調査JavaScriptの起源:その実装言語の調査Apr 29, 2025 am 12:51 AM

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

舞台裏:JavaScriptをパワーする言語は何ですか?舞台裏:JavaScriptをパワーする言語は何ですか?Apr 28, 2025 am 12:01 AM

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの未来:傾向と予測PythonとJavaScriptの未来:傾向と予測Apr 27, 2025 am 12:21 AM

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

Python vs. JavaScript:開発環境とツールPython vs. JavaScript:開発環境とツールApr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

JavaScriptはCで書かれていますか?証拠を調べるJavaScriptはCで書かれていますか?証拠を調べるApr 25, 2025 am 12:15 AM

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

See all articles

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SublimeText3 Mac版

SublimeText3 Mac版

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

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター