0

すべての着信メッセージを非常に高速に処理する必要があるWindowsアプリケーションがあります。そうしないと、システムのパフォーマンスがかなり低下すると思います。私が考えたのは、メッセージごとにスレッドを生成して結合し、それらが順番に処理されるようにする方法です。しかし、そのアプローチには深刻な問題があります。スレッドを生成してトップスレッドに参加しようとすると、参加できるかどうかをどのように知ることができますか?オフコース私はそれが参加可能かどうかをチェックできます(私はstd :: threadを使用します)が、それをしている間、それは単に参加できなくなり、スレッドはミューテックスではありません-私はそれをブロックしてもう一度チェックすることはできません。したがって、私が必要としているのは、少なくともメッセージスレッドに対して非ブロッキングである、ある種の遅延タスクプールまたはタスククエリです。ここでも、そのクエリを待機するスレッドを生成し、タスクを追加して処理できるようにすることができます。

それは必ずしも箱から出して機能するものではないでしょう、私は任意の同時パターンを実装することができます。

inb4:Windows、WinAPI、C ++ 11、スレッド用のstd::thread。私の英語で申し訳ありませんが、本当にそれを改善する時間が見つかりません。

ご回答ありがとうございます。問題の説明を間違えたようです。正確には、WNDPROCに結果をできるだけ早く返させるだけでよいので、次のメッセージをメッセージキューからポップできます。メッセージが送信された時間をログに記録するため、これが必要です。そのため、時間の測定に影響を与えないように、高速に実行する必要があります。また、これらのメッセージはシステムにとって緊急であり、私のウィンドウはそれらを高速に処理する必要があります。そうしないと、パフォーマンスに何らかの影響があります。

繰り返しますが、正確なメッセージ処理を他のスレッドに移動する必要があります。現在、次のようになっています。


case WM_INPUT:
    int timestamp = PushTimeStampToAsyncTimestampQueue();
    launchLongChainOfMessageProcessing(message,timestamp);
    return 0;

そのlaunchLongChainOfMessageProcessingを取り除き、次のようなものに置き換える必要があります


case WM_INPUT:
    int timestamp = PushTimeStampToAsyncTimestampQueue();
    std::thread processThread([]() { do_work(message, timestamp);});
    return 0;

4

1 に答える 1

4

現在のWindowsOSには、I /O完了ポート(略してIOCP)を使用したオーバーラップI / Oよりも高速でスケーラブルな、大量の受信メッセージの処理方法はありません。それは信じられないほどスケーラブルで非常に用途が広いです。

IOCPを使用すると、スレッドのプールを定義し、それらのスレッドをIOCPサブシステムによって管理およびスケジュールして、IOベースのシステム(ソケット、パイプ、ファイルなど、IOベースのシステムがない場合でも)でIO完了通知を待機できます好む;それは素晴らしいワークキュー配布システムにもなります)。

非常にエキセントリックな同時接続を処理するためにスレッドを生成しないように注意してください。安定したスレッドプールが必要です。プールは十分に大きく、イベントの待機やミューテックスなど、カーネルへの呼び出しでストールが発生したために1つがブロックされた場合に、別のスレッドがすぐにディスパッチされます。スレッドの生成、コンテキストの設定と破棄はコストがかかるため、回避してください。ありがたいことに、IOCPはまさにそれを行うための美しいソリューションです。仕事があり、他の人が他の仕事で忙しいときに、別のスレッドを眠りから解放する能力は非常に優れています。

私があなたが説明しているシステムをセットアップした場合(そして、与えられた場合、SOに関するいくつかの段落で、最終目標に対して非常に多くの正義を行うことができます)、私はためらうことなくIOCPベースのソリューションを使用します。

編集OPが質問を更新した後、私は奇妙なことにこの答えを支持するつもりですが、かなりねじれた方法で。彼は、そのメッセージキューの処理をできるだけ速くオフロードすることを望んでいます。非同期配信システムにWindowsメッセージキューを選択することはしませんが、彼には理由があると確信しています。

ただし、実際の処理にはIOCPベースのシステムを使用しています。スループットとスケーラビリティは、分散作業システムに使用するにはあまりにも優れているだけであり、彼がここに持っているもののようです。コードはありませんが、一般的なアルゴリズムはそうです。

  1. IOCPベースの作業員を作成します。すべてのスレッドがGetQueueCompletionStatus()を待機します。
  2. WM_INPUTを受信するたびに、必要なパラメーターを収集し、処理用の「アイテム」を作成し、PostQueuedCompletionStatus()を使用してIOCPベースの作業員にアイテムを投稿します(これは、作業に組み込むのに最も便利な方法です。 -乗組員の「ポスト」機能)。
  3. 各スレッドが目覚めると、処理する作業「アイテム」がスレッドに渡されます。
  4. アイテムの処理が完了すると、プールスレッドはGetQueueCompletionStatus()に戻ります。

Web上には多数のサンプルIOCPベースのワークキューがあり、そのほとんどがこのニーズに適しています。すべては、悪鬼によって書かれていない限り、IOCPがスケジュールに非常に緊密に統合されているため、Windowsで使用できる他のほとんどのものよりも優れたパフォーマンスを発揮します。

于 2012-10-01T08:19:21.247 に答える