5

リモート マシンからメッセージを受信し、そのメッセージをディスク上のファイルに書き込む必要があるプログラムを作成しています。私が見つけている困難は、このプログラムの目的がメッセージを受信するライブラリのパフォーマンスをテストすることであるため、メッセージをディスクに書き込むことがライブラリのパフォーマンスに影響を与えないことを確認する必要があるという事実にあります. ライブラリは、コールバック関数を介してメッセージをプログラムに配信します。もう 1 つの問題は、ソリューションがプラットフォームに依存しないことです。

どのようなオプションがありますか?

私は次のことを考えました:

  • boost:asioファイルへの書き込みに使用していますが、ファイルへの非同期書き込みはこのライブラリの Windows 固有の部分にあるようです (このドキュメントを参照)。したがって、これは使用できません。
  • を使用boost::interprocessしてメッセージキューを作成しますが、このドキュメントは、メッセージを送信できる方法が3つあり、メッセージキューがいっぱいの場合、すべての方法でプログラムをブロックする必要があることを示しています(暗黙的または非明示的)。
  • を作成しstd::deque<MESSAGES>てコールバック関数から両端キューにプッシュし、ファイルへの書き込み中に (別のスレッドで) メッセージをポップアウトしますが、STL コンテナーはスレッドセーフであるとは限りません。両端キューへのプッシュとポップオフをロックすることはできますが、連続するメッセージ間の間隔は約 47 マイクロ秒であるため、ロックを完全に回避したいと考えています。

考えられる解決策について、これ以上のアイデアはありますか?

4

2 に答える 2

2

STL コンテナはスレッド セーフではないかもしれませんが、異なるスレッドで異なる時間に使用できないコンテナにヒットしたことはありません。所有権を別のスレッドに渡すことは安全に思えます。

私は以下を数回使用したので、それが機能することを知っています:

  • std::vector へのポインターを作成します。
  • ベクトル ポインターを保護するためにミューテックス ロックを作成します。
  • new[] を使用して std::vector を作成し、次に大きなサイズの reserve() を作成します。

受信側スレッドで:

  • アイテムをキューに追加するたびにミューテックスをロックします。これは短いロックである必要があります。
  • キュー アイテムを追加します。
  • ロックを解除します。
  • 条件変数を通知するように感じたら。私は時々そうしません:それはデザインに依存します。ボリュームが非常に高く、受信側に一時停止がない場合は、条件をスキップして代わりにポーリングします。

コンシューマー スレッド (ディスク ライター) で:

  • 条件変数をポーリングまたは待機して、実行する作業を探します。
  • キューミューテックスをロックします。
  • キューの長さを見てください。
  • キューに作業がある場合は、ポインタをコンシューマ スレッドの変数に割り当てます。
  • new[] と reserve() を使用して新しいキュー ベクトルを作成し、それをキュー ポインターに割り当てます。
  • ミューテックスのロックを解除します。
  • 離れて、アイテムをディスクに書き込みます。
  • delete[] 使い切ったキュー ベクトル。

問題によっては、ブロックする方法が必要になる場合があります。たとえば、私のプログラムの 1 つで、キューの長さが 100,000 アイテムに達した場合、生成スレッドは 1 秒間のスリープを開始し、多くの文句を言い始めます。これは、発生してはならないことの 1 つですが、実際に発生しているため、考慮する必要があります。制限がまったくない場合、マシン上のすべてのメモリを使用してから例外でクラッシュするか、OOM によって強制終了されるか、スワップ ストームで停止します。

于 2012-11-17T00:25:27.830 に答える
2

boost::thread はプラットフォームに依存しないため、スレッドを作成してブロッキング書き込みを行うことができるはずです。メッセージがメイン スレッドに配置されるたびにコンテナーをロックする必要がないようにするには、次のような入れ子になったコンテナーを作成して、ダブル バッファリング手法を変更します。

std::deque<std::deque<MESSAGES> >

次に、メッセージでいっぱいの両端キューを追加する準備ができたときにのみ、最上位の両端キューをロックします。書き込みスレッドは、最上位の両端キューのみをロックして、書き込まれるメッセージでいっぱいの両端キューをポップオフします。

于 2012-11-16T22:14:18.107 に答える