web-dev-qa-db-ja.com

Linux上のプロセス間でメッセージを渡す最速のテクニックは?

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

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

他に方法はありますか、また最速のものは何ですか?

35
user997112

これもご覧になることをお勧めします: CでLinuxで共有メモリを使用する方法

基本的に、1台のマシンでTCPを実行するときにIPCおよびUDPのようなネットワークプロトコルをドロップします。これらはパケットのオーバーヘッドがあり、さらに多くのリソースにバインドされます。 (例:ポート、ループバックインターフェイス)。

13
Sam

上記の答えはすべて非常に優れていますが、「最速」とは何かを議論する必要があると思います[そして、それは「最速」である必要がありますか?

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

ただし、メッセージが小さい場合は、独自のメッセージ受け渡しプロトコルと、メッセージがあることを他のプロセスに通知する方法を考え出す必要があるという欠点があります。

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

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

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

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

もちろん、別の考慮事項は、「この問題を解決するために、2台の別々のマシン(または同じシステム上の2台の仮想マシン)を使用することです。その場合、ネットワークソリューションの方が優れています。 、ベンチマークのために職場のマシンでローカルTCPスタックを実行し、20-30Gbit/s(2-3GB/s)の持続的なトラフィックを取得しました。同じプロセスは約50〜100 GBit/s(5〜10 GB/s)になります(ブロックサイズが本当に小さく、L1キャッシュに収まらない限り)。標準のパイプを測定していませんが、だいたい中央にあると思います。 [これは、中規模のさまざまなかなり現代的なPCにほぼ適切な数値です-明らかに、ARM、MIPS、またはその他の組み込みスタイルのコントローラーでは、これらのすべてのメソッドで低い数値を想定しています]

38
Mats Petersson

英国ケンブリッジ大学の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

8
DejanLekic

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

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

3
Alex

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

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

ソース

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

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

同期を伴う共有メモリは、大量のデータが関係する場合に適したアプローチです。

2
pepper_chico

Linux共有メモリ aka SHMを使用して、プロセス間に共有メモリセグメントを簡単に作成できます。

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

1
cmc

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

0
arash kordi