5

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

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

私は、次の考え:ファイルへの非同期書き込みは、このライブラリのWindowsの特定の部分であること(thisマニュアルを参照してください)ファイルに書き込むboost:asioを使用して

  • が、それはそうです - ので、これをすることはできません中古。
  • boost::interprocessを使用してメッセージキューを作成すると、this documentationは、メッセージを送信できる方法が3つあり、メッセージキューがいっぱいであればプログラムがブロックする(暗黙的にもそうでない)リスク。
  • を作成してコールバック関数から両端キューにプッシュし、ファイルへの書き込み中に別のスレッドにメッセージをポップしますが、STLコンテナはnot guaranteed to be thread-safeです。私はデッキへのプッシュとプッシュオフをロックすることができますが、連続したメッセージ間で約47マイクロ秒を話しているので、ロックを完全に避けたいと思います。

誰も解決策について考えていますか?

+0

47マイクロメッセージですか?リモートマシンのリズムですか? –

答えて

2

STLコンテナはスレッドセーフではない可能性がありますが、別のスレッドで別の時間に使用できないものはありません。所有権を別のスレッドに渡すことは安全です。私は数回以下の使用しているので、私はそれが動作を知って

  • がのstd ::ベクトルへのポインタを作成します。
  • ベクトルポインタを保護するためのmutexロックを作成します。
  • 新しい[]を使用してstd :: vectorを作成し、大きなサイズを予約します()。受信スレッドで

:キューに項目を追加するたびに

  • ミューテックスをロック。これは短いロックでなければなりません。
  • キューアイテムを追加します。
  • ロックを解除します。
  • 条件変数を通知するように感じたら、私は時々そうしない:それはデザインに依存する。ボリュームが非常に高く、受信側にポーズがない場合は、条件をスキップして代わりにポーリングしてください。消費者スレッド(ディスクライター)で

  • Goではポーリングによってやるべき仕事探しや条件変数を待っている:
  • キューミューテックスをロックします。
  • キューの長さを調べます。
  • キューに作業がある場合は、コンシューマスレッド内の変数にポインタを割り当てます。
  • 新しい[]とreserve()を使用して新しいキューベクトルを作成し、それをキューポインタに割り当てます。
  • ミューテックスのロックを解除します。
  • あなたのアイテムを取り出し、ディスクに書き出します。
  • delete []使用済みキューベクトル。

問題によっては、ブロックする方法が必要になることがあります。例えば、私のプログラムの一つでは、待ち行列の長さが100,000個に達した場合、生成スレッドはちょうど1秒のスリープを開始し、多くの不平を言うようになります。それは起こるべきではないものの一つですが、あなたはそれを考慮する必要があります。何も制限がなければ、マシン上のすべてのメモリを使用し、例外でクラッシュするか、OOMによって殺されるか、またはスワップストームで停止するだけです。

+0

他の答えを読みました。アイテムごとのロックが高すぎる場合は、この要件にも適応できます。ベクトルポインタのベクトルを保持し、それを書き終えたらベクトルを追加するだけです。 –

+0

もう1つの注意:この設計は、mutexが競合がない場合に非常に低コストのフューテックスを使用するLinux上で私にとっては本当にうまくいっています。 CriticalSectionを使用するBSDやWindowsでは悪いことではありません。しかし、非常にマルチプラットフォームになりたいので、入れ子にされたコンテナのロックが本当に最高かもしれません。 –

2

boost :: threadはプラットフォームに依存しないため、スレッドを作成してブロック書き込みをオンにする必要があります。

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

続いた場合にのみ、トップレベルの両端キューをロック:あなたのようなネストされたコンテナを、作成することにより、ダブルバッファリング技術上の変更を利用することができた容器にメッセージをメインスレッドに置かれるたびにロックする必要がないようにするにメッセージのいっぱいが追加される準備ができています。書き込みスレッドは、最上位のデキューをロックするだけで、書き込まれるべきメッセージがいっぱいになってしまう。

関連する問題