【解決方法】スレッドの枯渇を防ぐ – ベスト プラクティス

プログラミングQA


複数のプロセッサ/コア間で最大 200 個のスレッドを同時に実行する可能性があるアプリケーションまたはサービスでのスレッドの枯渇/ブロッキング/競合を防ぐ方法に関する詳細情報を探しています。

私がオンラインで見つけた例のほとんどは、最大 3 つまたは 4 つのスレッドの間で調整する方法を示しており、私は数百ものスレッドを持つアプリを計画しています。

最大 30 スレッドで実行するアプリケーションを作成しましたが、それをはるかに超えると、一部のスレッドが同期はおろか CPU 時間を取得できないのではないかと心配になります。

本当に良い記事やブログはどこで見つけられますか?
このテーマに関する最高の本は何ですか?
このテーマに関する本や記事はたくさんありますが、最も有益で教育的なものを探していますが、私の理解を超えるエンジニアリング言語で説明されていません。

すべてのご提案を歓迎いたします。

解決策 1

取り上げるシナリオが多すぎるため、ご質問に答えることができません。

ただし、コアの数より多くのアクティブなスレッドを使用すると、通常は逆効果になります。 コア数よりも多くのスレッドを使用すると、ほとんどのスレッドが通常スリープ状態になりたい場合にのみメリットが得られます。たとえば、ネットワークからデータを受信する recv() 呼び出しなどの一部の IO 操作を待機する場合に限られます。 その場合でも、並列実行するスレッドの数を積極的に制御する必要があるため、コアが 4 つある場合、そのうちの 4 つだけが並列実行されることを期待して 200 個のスレッドを開始するのは良い習慣ではありません。

常にアクティブな 200 個の並列タスクを実行する必要がある場合は、コアの数と同じ数のスレッドのみを作成し、タスクを小さなジョブに分割する方が良いでしょう。 これらの小さなジョブをジョブ キューに投入し、スレッドがそこから 1 つずつ取り出して、任意の順序でスレッド上で実行します。 これはすでに独自のスケジューラを持つことに近づいています。 以前の解決策よりも洗練された解決策が得られることが多い手法は、グリーン スレッド/コルーチン (一部の Linux ディストリビューションでは非推奨の ucontext POSIX API、Windows ではファイバー API) を使用することです。

グリーン スレッドを使用すると、スレッドを多数のグリーン スレッドに分割し、これらのグリーン スレッド間のタスクの切り替え/連携をユーザー空間で明示的に実行できます。 4 つのコアがあるとします。 次に、4 つのスレッドを開始し、各スレッドを 100 個のグリーン スレッドに分割すると、400 個のグリーン スレッドが存在しますが、常にそのうちの 4 つだけが並列実行され、制御できるため独自のスケジューラを作成できます。タスクは緑色のスレッド間で切り替わります。

たとえば、グリーン スレッドを使用して Web サーバーを作成すると、次の利点があります。通常のマルチスレッド実装と非同期/グリーン スレッド実装のコードは、適切に記述されていれば同じサーブレット コードを使用できます (そうでない場合は、タスクの切り替えを独自の実装に組み込むことができるため)。ソケットの読み取り/書き込み関数などのブロッキング関数呼び出しと、マルチスレッド モードでの同じブロッキング関数呼び出しの実装は、実際にはブロッキング OS の同等の関数を呼び出しています)。

コメント

タイトルとURLをコピーしました