10

Linuxでカーネル2.6を使用してネットワークデーモンを作成しています。このデーモンには、 1つのプロデューサープロセスとN個のコンシューマープロセスがあり、データに変更を加えず、プロデューサーへの応答を作成しません。

プロデューサープロセスは、長さが数10バイトから数10 Kバイトまで変化するデータオブジェクトを生成するときはいつでも、データオブジェクトを1つの使用可能なコンシューマープロセスに渡す必要があります。

初めて、名前付き/名前なしのパイプを使用することを検討しました。ただし、それらはメモリコピーのオーバーヘッドになります。

  1. プロデューサーのユーザースペースバッファー--copy->カーネルスペースPIPEバッファー
  2. カーネルスペースPIPEバッファー--copy->コンシューマーのユーザースペースバッファー

プログラムは待ち時間の短い多数のピアで動作する可能性があるため、コピーオーバーヘッドは有害である可能性があります。そのため、mmap()でPOSIX共有メモリを使用することにしました。

POSIX共有メモリをmmap()で使用してプロセス間でデータを共有しても、PIPEとは異なり、メモリコピーが発生しないのではないかと思っています。

また、プロセス間でデータを共有する他の方法はありますが、結果はゼロコピーになりますか?プログラムは、最新バージョンのカーネルを搭載したLinuxで実行され、クロスプラットフォーム機能を備えている必要はない場合があります。

コンシューマー/プロデュースごとにスレッドを生成/実行するのではなく、設計上の問題のためにプロセスを実行することにしました。

返信ありがとうございます。

4

3 に答える 3

6

一般に、共有メモリは、コピーのオーバーヘッドを引き起こさないように特別に設計されています(ソース:http ://www.boost.org/doc/libs/1_46_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.sharedmemory.shared_memory_what_is )。

C ++を使用している場合、Boost :: Interprocessは、クロスプラットフォームの方法で記述しているものを実装するための優れたライブラリです。共有メモリクラスをnamed_upgradable_mutexと組み合わせて使用​​できます。named_upgradable_mutexクラスは、リソースに排他的で共有可能なロックを与えることをサポートしているため、それを使用してコンシューマープロデューサーモデルを簡単に実装できます。(ソース:http ://www.boost.org/doc/libs/1_37_0/doc/html/boost/interprocess/named_upgradable_mutex.html#id2913393-bb )

于 2011-02-27T00:00:54.993 に答える
2

共有メモリはコピーを導入するべきではなく(キャッシュコヒーレンシを除く)、メモリに直接アクセスできるため、コード内のコピーを回避できる可能性があります。

于 2011-02-26T23:53:32.423 に答える
0

はい、ゼロコピーである必要があります。

ただし、これは(おそらく時期尚早の)最適化でもあり、プロセスが共有メモリの割り当て/割り当て解除/変更と適切に連携するように十分な注意を払う必要があります。同時アクセスの問題を回避するには、確かに何らかのミューテックスが必要です。

個人的には、パフォーマンスが適切な問題になるまでパイプを使用します。実際にそうであれば、Boost::Interprocessまたは同様のライブラリを使用することをお勧めします。

于 2011-02-27T08:11:53.420 に答える