糸を通すか、糸を使わないか?それが質問です...
質問のマルチスレッド部分に対する単純で正しい答えは次のとおりです。はい、1) アルゴリズムに従って実現可能であり、2) I/O バウンド ops を含むか、CPU バウンド ops に複数のコアがある場合、すぐに
最初のポイント: 実現可能性
- ステップ 2 を実行するには、ステップ 1 を完了する必要があります。マルチスレッドはまだありません
- ステップ 3 では、ステップ 2 を完了する必要がありますが、独立した行ごとのアクティビティ (行ごとに 1 つの要求)が含まれます。ビンゴ!!
- ステップ 4 では、ステップ 3 ですべての要求を完了する必要があります。マルチスレッドはそこで終了します。
2点目:操作の種類
Web リクエストは I/O バウンド操作です。最大の利益を得ることができます。フォールトトレラントかどうかに関係なく、同じサーバーに対してリクエストを実行しているため、クエリレートを制限する必要があります。同時リクエストの数を適切に調整する必要がありますが、コードで定数を使用する場合 ( などconst int NUMBER_OF_THREADS = 4;
) は、適切な出発点になります。
提案
セマフォを使用して同時要求を処理します。
前に行ったように、ファイルを読み取り、中間ファイルに変換してプログラムを開始します。
終了したら、固定サイズの配列を作成し(最終ファイルには同じ数の行があるため、割り当てることができると述べました)、各行のループを開始します。
- 定数で初期化されるセマフォを取得します
NUMBER_OF_THREADS
。これにより、メイン スレッドは 4 つの同時スレッドをアクティブにできます。
- 行、ターゲット配列、およびインデックスを渡してスレッドを開始します (リストがクラス メンバーである場合、実際にはそれらすべてをパラメーターとして渡す必要はありません)。
ループの後、AutoResetEvent
簡単に説明するのを待ちます
スレッドで、次の操作を行います。
- Web リクエストを実行する
- 処理結果
- 結果を対応するターゲット配列行に保存します
- メソッドを使用して、スレッド間で共有される変数(ここでは説明しません) をインクリメントします。
Interlocked.Increment()
if
共有変数equals
行数、私が言及したものをthen
解放すると、AutoResetEvent
メインスレッドのロックが解除されます
チューニング
4 つの同時スレッドから始めます。それらを 8 に増やして、パフォーマンスを確認してください。12 スレッドを超えないようにすることをお勧めしますが、ここにいる他の人は、それは多すぎるかもしれないと言うかもしれません... それは試行錯誤です。