44

Linux で C++ アプリケーション プロセス間でメッセージを送信する最速のテクノロジは何ですか? 私は、次のテクニックが検討されていることを漠然と認識しています。

  • TCP
  • UDP
  • ソケット
  • パイプ
  • 名前付きパイプ
  • メモリ マップト ファイル

他に方法はありますか?最速は何ですか?

4

7 に答える 7

49

上記の回答はすべて非常に優れていますが、「最速」とは何かについて議論する必要があると思います[そして、「最速」である必要がありますか、それとも単に「」に十分な速さである必要がありますか?]

LARGE メッセージの場合、共有メモリが非常に優れた手法であり、多くの点で非常に役立つことは間違いありません。

ただし、メッセージが小さい場合は、独自のメッセージ パッシング プロトコルと、メッセージがあることを他のプロセスに通知する方法を考え出さなければならないという欠点があります。

この場合、パイプと名前付きパイプを使用する方がはるかに簡単です。これらはファイルのように動作し、送信側でデータを書き込み、受信側でデータを読み取るだけです。送信側が何かを書き込むと、受信側が自動的にウェイクアップします。パイプがいっぱいになると、送信側がブロックされます。送信者からのデータがなくなると、受信側は自動的にブロックされます。つまり、これはかなり少ないコード行で実装できることを意味し、いつでも、いつでも機能するというかなりの保証があります。

一方、共有メモリは、他のメカニズムに依存して、「処理するデータのパケットがある」ことを他のスレッドに通知します。はい、コピーするデータのパケットが大きい場合は非常に高速ですが、パイプに大きな違いがある場合は驚くでしょう。主な利点は、相手側が共有メモリからデータをコピーする必要がないことですが、すべての「飛行中」のメッセージを保持するのに十分なメモリがあるか、送信者が物事を抑える能力を持っていることにも依存しています。 .

「共有メモリを使用しない」と言っているのではなく、「すべての問題を「最善」に解決する 1 つのソリューション」などというものは存在しないと言っているだけです。

明確にするために:パイプまたは名前付きパイプを使用して単純なメソッドを実装することから始めます[目的に応じて]、そのパフォーマンスを測定します。実際にデータをコピーするのにかなりの時間が費やされる場合は、他の方法を使用することを検討します。

もちろん、もう 1 つの考慮事項として、「この問題を解決するために 2 台の別々のマシン [または同じシステム上の 2 台の仮想マシン] を使用する予定があるかどうか」があります。 、ベンチマークの目的で職場のマシンでローカル TCP スタックを実行したところ、持続的なトラフィックで 20 ~ 30Gbit/s (2 ~ 3GB/s) が得られました。同じプロセス内の raw memcpy は約 50 ~ 100Gbit/s を取得します(5-10GB/s) (ブロックサイズが非常に小さく、L1 キャッシュに収まる場合を除く) 標準的なパイプを測定したことはありませんが、これら 2 つの数値のほぼ中間にあると予想されます。これは、さまざまな中規模のかなり最新の PC の多くにほぼ適しています - 明らかに、ARM、MIPS、またはその他の組み込みスタイルのコントローラーでは、これらすべての方法でより低い数値が期待されます]

于 2013-01-08T23:25:03.130 に答える
18

これも見てみることをお勧めします:CでLinuxで共有メモリを使用する方法

基本的に、単一のマシンでIPCを実行する場合は、TCPやUDPなどのネットワークプロトコルを削除します。これらにはパケット化のオーバーヘッドがあり、さらに多くのリソース(ポート、ループバックインターフェイスなど)にバインドされます。

于 2013-01-08T22:24:34.827 に答える
11

英国ケンブリッジ大学の NetOS Systems Research Group は、いくつかの (オープンソース) IPC ベンチマークを実行しました。

ソース コードはhttps://github.com/avsm/ipc-benchにあります。

プロジェクトページ: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ .

結果: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

この研究は、上記の結果を使用して公開されています: http://anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf

于 2015-11-06T14:37:12.623 に答える
3

CMAとkdbusを確認してください: https ://lwn.net/Articles/466304/

最近の最速のものはAIOに基づいていると思います。 http://www.kegel.com/c10k.html

于 2013-01-08T22:24:32.253 に答える
3

この質問に C++ のタグを付けたので、Boost.Interprocessをお勧めします。

共有メモリは、最速のプロセス間通信メカニズムです。オペレーティング システムは、メモリ セグメントを複数のプロセスのアドレス空間にマップします。これにより、複数のプロセスが、オペレーティング システムの関数を呼び出さずにそのメモリ セグメントを読み書きできるようになります。ただし、共有メモリを読み書きするプロセス間で何らかの同期が必要です。

ソース

私が見つけた 1 つの警告は、同期プリミティブの移植性の制限です。たとえば、OS X も Windows もプロセス間条件変数のネイティブ実装を持っていないため、スピン ロックでそれらをエミュレートします。

POSIX プロセス共有プリミティブをサポートする *nix を使用する場合、問題はありません。

同期を使用した共有メモリは、大量のデータが含まれる場合に適した方法です。

于 2013-01-09T08:35:16.253 に答える
2

Linux共有メモリ(別名)を使用して、プロセス間に共有メモリセグメントを設定することもできますSHM

使い方はとても簡単です。いくつかの例については、リンクをご覧ください。

于 2013-01-08T22:24:10.960 に答える
0

posix メッセージ キューは非常に高速ですが、いくつかの制限があります。

于 2013-07-28T12:51:17.087 に答える