#nodejs は集中的な計算をどのように処理しますか?
Nodejs 集中型 CPU ソリューション
最初に、nodejs シングル スレッドの利点について話しましょう:
推奨: "javascript Advancedチュートリアル>>
PHP と比較してパフォーマンスが高く、スレッドの頻繁な作成と切り替えによるオーバーヘッドを回避し、より高速に実行され、使用するリソースが少なくなります。
スレッドの安全性。複数のスレッドによって同じ変数が読み書きされてプログラムがクラッシュすることを心配する必要はありません。
シングルスレッドの非同期およびノンブロッキング。実際、基盤となるnodejsアクセスI/Oは依然としてマルチスレッドです。ブロッキング/ノンブロッキングと非同期/同期は2つの異なる概念です。同期はブロッキングを意味しません。 , しかし、ブロックは間違いなくそうなります。同期です。少し複雑です。例を教えてください。食事を準備するために食堂に行きました。セット A を選択しました。その後、スタッフが食事の準備を手伝ってくれました。私がただ脇にいて、スタッフが食事の準備をするのを待っていた場合、この状況は次のようになります。これは同期と呼ばれます。スタッフが食事の準備を手伝っている場合、私の後ろの人が注文を開始します。そのため、食堂全体の注文サービスが停止することはありません。定食Aを待っています。この状況をノンブロッキングと呼びます。この例は、同期的だがブロックされていない状況を簡単に示しています。また、料理が提供されるまでの間にドリンクを購入し、番号が呼ばれたときに再度定食を取りに行くと、すでにドリンクは購入されています。 , 私も飲み物を買うというタスクを実行します。番号に電話をかけることは、コールバックが実行されると、非同期でノンブロッキングになります。ドリンクを買うときに、定食をもらうために番号を呼ばれたけど、ドリンクを受け取るまでに長時間待たなければならないため、食事の番号が終わってからかなり時間が経ってからA定食を手に入れることができない場合があります。ロビーで呼び出されます。これは、シングル スレッドのブロック状況です。
マルチスレッド:
スレッドは CPU スケジューリングの基本単位であり、CPU は 1 つのスレッド タスクのみを実行できます。
nodejs は、TAGG/TAGG2 モジュールの参照などのマルチスレッド タスクも実行できますが、tagg/tag2 はどちらも pthread ライブラリと V8::Isolate クラスを使用して js マルチスレッド関数を実装します。ルール上、スレッド内で実行される関数は fs や crypto モジュールなどの nodejs のコア API を使用できないため、依然として大きな制限があります。
複数のプロセス:
HTML5 をサポートするブラウザでは、Webworker を使用して、時間のかかる計算をワーカー プロセスにスローして実行できるため、メイン プロセスがブロックされず、ユーザー ラグ感はありません。
ここでは、nodejs の child_process モジュールを使用する必要があります。Child_process は、nodejs ファイルを開始してそれをワーカー プロセスと見なすことができる fork メソッドを提供します。ワーカーが作業を完了すると、結果がに送信されますメインプロセスを実行すると、ワーカーが自動的に終了するため、複数のプロセスを使用してメインスレッドのブロックの問題を解決できます。
var express = require('express'); var fork = require('child_process').fork; var app = express(); app.get('/', function(req, res){ var worker = fork('./work.js') //创建一个工作进程 worker.on('message', function(m) {//接收工作进程计算结果 if('object' === typeof m && m.type === 'fibo'){ worker.kill();//发送杀死进程的信号 res.send(m.result.toString());//将结果返回客户端 } }); worker.send({type:'fibo',num:~~req.query.n || 1}); //发送给工作进程计算fibo的数量 }); app.listen(7878);
Express を介してポート 7878 をリッスンします。ユーザーのリクエストごとに、子プロセスをフォークし、worker.send メソッドを呼び出してパラメーター n を子プロセスに渡し、同時にリッスンします。子プロセスが送信したメッセージのメッセージイベントを取得し、その結果をクライアントに応答します。
フォークされた work.js ファイルの内容は次のとおりです。
var fibo = function fibo (n) {//定义算法 return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; } process.on('message', function(m) { //接收主进程发送过来的消息 if(typeof m === 'object' && m.type === 'fibo'){ var num = fibo(~~m.num); //计算jibo process.send({type: 'fibo',result:num}) //计算完毕返回结果 } }); process.on('SIGHUP', function() { process.exit();//收到kill信息,进程退出 });
まず、フィボナッチ配列を計算する関数 fibo を定義し、次にメイン スレッドによって送信されたメッセージをリッスンします。計算が完了したら、結果をメインスレッドに送信します。同時に、プロセスの SIGHUP イベントもリッスンし、このイベントがトリガーされると、プロセスは終了します。
ここで注意する必要があるのは、メイン スレッドの kill メソッドは実際には子プロセスを終了させるのではなく、子プロセスの SIGHUP イベントをトリガーするということです。実際の終了は引き続きプロセスに依存します。出口()。
要約:
child_process モジュールの fork メソッドを使用すると、シングルスレッドの CPU 集中型タスクのブロッキング問題を解決できます。 tagg パッケージを含まない Node.js コア API の制限。
シングルスレッドの非同期 Node.js は、ブロックされないという意味ではありません。メイン スレッドで実行するタスクが多すぎると、メイン スレッドがスタックし、プログラム全体のパフォーマンスに影響を与える可能性があります。ループ、文字列の結合、浮動小数点演算などの CPU を大量に使用するタスクの場合は、さまざまなテクノロジを合理的に使用して、タスクをサブスレッドまたはサブプロセスに割り当てて完了させ、 Node.js メインスレッドが開きます。
スレッド/プロセスの使用にはオーバーヘッドが伴います。作成および破棄されるスレッド/プロセスの数をできる限り減らすことで、システム全体のパフォーマンスとエラーの確率を向上させることができます。
以上がNodejs が集中的な計算を処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。