サーバーとして機能するクラス オブジェクトがあります。どこからでもリクエストを受信し、そのリクエストをリクエスト キューにプッシュします ( Producer
)。これで、リクエスト キューからリクエストをポップし、リクエストを提供する適切なクラス メソッドを呼び出すリクエストに基づいて実行中のコンシューマ スレッドがあります。これで、キューからのリクエストの消費と適切な関数の起動が同期的に実行されます。私が望むのは、消費者スレッドがキューからリクエストをポップアップし、適切な関数を非同期的に起動して、消費者がキューから次のリクエストをすぐにポップできるようにすることです。
私がこれで試した解決策の 1 つは、消費者がキューから要求をポップアップしboost::thread
、新しいスレッドで適切な関数を作成して開始することです。スレッド ポインターを保存しstd::vector
ただけでなく、 も試しboost::thread_group
ました。ここまでは順調ですね。しかし、このソリューションには問題があります。
150 を超えるリクエストを送信すると、150 を超えるスレッドが存在し、その後、 pthread
新しいスレッドが作成されず、エラーが発生します"pthread_create: Resource temporarily unavailable"
。これは、現在のプロセスのスタックが不足しているため、新しいスレッドを作成できないことを意味すると考えられます。
質問 #1私のリクエスト ハンドラーには が含まれていませんwhile (1)
。これらは何らかの作業を行って終了しているだけで、何も待機していません。そのため、最初のスレッドが処理を完了し、スレッド ハンドラー関数から終了したと予想しています。スレッドが処理を完了して終了した場合、これを考慮して、スタックからその内容をクリーンアップするべきではありませんか?
この問題の解決策の 1 つは、スレッドのスタック サイズを設定することですが、1000 スレッド後もこのエラーが発生します。
したがって、私の要件は、しばらくしてから完了したスレッドをクリーンアップする必要があることです (つまり、スレッド ポインターのベクトルが 100 を超えたとき、または 1 分ごとなど)。
質問 #2上で述べたように、新しいスレッドを起動する以外に、試してみるべき非同期関数呼び出しメカニズムは何ですか。boost::function
+はboost::bind
非同期ですか? これは私が言及した状況に対する良い解決策ですか? 私のシステムは 24 時間 365 日オンラインで、毎日 1000 件以上のリクエストを受け取っているとします。
更新 #1 それで、私の設計に 1 つの問題が見つかりました。質問 #1 で、私のリクエスト ハンドラーには単純な呼び出しだけが含まれていると述べましたが、これは真実ではないことがわかりました。サーバーからファイルを同期的にダウンロードしていますが、これは基本的にブロック操作です。ファイルを非同期でダウンロードする必要があります。
要求ハンドラーがブロッキング操作を行っていない場合、基になるシステムが同時に処理できないスレッドを作成しても意味がありません。
したがって、Alex が複数のコンシューマー スレッド (5 つあれば十分だと思います) を使用してキューからリクエストをポップし、非同期ファイルをダウンロードすることで問題が解決すると述べたように。