イベントループは、コンピュータシステムが動作するメカニズムを指す重要な概念です。
JavaScript言語は、シングルスレッド操作に関連するいくつかの問題を解決するために、このメカニズムを使用しています。
イベントループを理解するには、プログラムの実行モードから始める必要があります。後から実行されるプログラムは「プロセス」と呼ばれ、一般的にプロセスは一度に1つのタスクしか実行できません。
実行すべきタスクが多ければ、解決策は3つまで。
キューイング。プロセスは一度に1つのタスクしか実行できないため、次のタスクを実行する前に前のタスクが終了するのを待たなければなりません。
新しいプロセス。fork コマンドを使って、タスクごとに新しいプロセスを作成します。
新しいスレッド。プロセスはリソースを大量に消費するため、今日のプログラムでは、プロセスに複数のスレッドを含めることができ、スレッドがタスクを実行することがよくあります。
例えばJavaScriptはシングルスレッド言語であり、すべてのタスクはシングルスレッド、つまり上記の****メソッドで完了します。ひとたび大量のタスクが発生したり、時間のかかるタスクが発生したりすると、JavaScriptはユーザーの行動を停止して対応することができないため、ウェブページは「死んだふり」をしているように見えます。
なぜJavaScriptはシングルスレッドなのか、マルチスレッドとして実装できないのかと聞かれるかもしれません。
これは歴史と関係があります。JavaScriptはその初期からシングルスレッドでした。その理由はおそらく、ブラウザを複雑にしたくなかったからでしょう。複数のスレッドはリソースを共有する必要があり、お互いの結果を変更する可能性もあるため、ウェブスクリプト言語としては複雑すぎるからです。その後、JavaScriptはシングルスレッド言語であることが合意されました。
I/O操作を多用するような時間のかかるタスクの場合、スレッドはおそらく次のように実行されるでしょう。
上のグラフの緑の部分がプログラムの実行時間で、赤い部分が待ち時間です。ご覧のように、I/O操作は遅いので、このスレッドは実行時間のほとんどをI/O操作の戻り結果を待つことに費やしています。このような操作は「同期モード」または「ブロッキング・モード」と呼ばれます。
マルチスレッドを使って複数のタスクを同時に実行すると、ほとんどの場合、次のようになります。
上の図は、複数のスレッドがシステムリソースを何倍も占有するだけでなく、何倍ものリソースをアイドル状態にしていることを示しており、明らかに不合理です。
イベントループはこの問題を解決するために提案されました。ウィキペディアではこのように定義されています:
「イベント・ループは、メッセージやイベントを待ち、送信するプログラム構造です。
1つは「メイン・スレッド」と呼ばれるプログラム自体の実行を担当し、もう1つは「イベント・ループ・スレッド」と呼ばれるメイン・スレッドと他のプロセス間の通信を担当します。
上のメインスレッドの緑色の部分はまだ実行時間を示し、オレンジ色の部分はアイドル時間を示しています。I/Oが発生するたびに、メインスレッドはイベントループスレッドに対応するI/Oプログラムを通知させ、逆方向に実行を進めるので、赤い待ち時間は発生しません。I/Oプログラムが処理を完了すると、イベントループスレッドは結果をメインスレッドに返します。その後、メインスレッドは定義済みのコールバック関数を呼び出してタスクを完了します。
ご覧のように、メイン・スレッドはオレンジの空き時間が増えるため、より多くのタスクを実行できるようになり、効率が向上します。このような動作を「非同期モード」または「ノンブロッキングモード」と呼びます。
これはまさにJavaScript言語の仕組みです。シングルスレッド・モデルは、JavaScript に大きな制限を課す一方で、結果として他の言語にはない利点をもたらします。適切にデプロイされれば、JavaScriptのプログラムが詰まることはありません。そのため、node.jsプラットフォームは非常に少ないリソースで高いトラフィックに対応することができます。




