80

Unix/Linux では、パイプ、ソケット、共有メモリ、dbus、メッセージ キューなど、多くの IPC が提供されています。

それぞれに最も適したアプリケーションは何ですか?また、それらはどのように機能しますか?

4

4 に答える 4

105

Unix IPC

ビッグセブンは次のとおりです。

  1. パイプ

    親/子として関連するプロセス間でのみ有用です。pipe(2)と を呼び出しfork(2)ます。単方向。

  2. FIFO、または名前付きパイプ

    プレーン パイプとは異なり、関連のない 2 つのプロセスが FIFO を使用できます。コールしmkfifo(3)ます。単方向。

  3. ソケットUnix ドメイン ソケット

    双方向。ネットワーク通信用ですが、ローカルでも使用できます。異なるプロトコルに使用できます。TCP にはメッセージ境界がありません。コールしsocket(2)ます。

  4. メッセージ キュー

    OS は個別のメッセージを維持します。sys/msg.hを参照してください。

  5. 信号

    Signal は整数を別のプロセスに送信します。マルチスレッドとうまく噛み合わない。コールしkill(2)ます。

  6. セマフォ

    トイレを待つ人々の列に似た、マルチプロセスまたはスレッドの同期メカニズム。sys/sem.hを参照してください。

  7. 共有メモリ

    独自の同時実行制御を行います。コールしshmget(2)ます。

メッセージ境界の問題

どちらか一方の方法を選択する際の決定要因の 1 つは、メッセージ境界の問題です。「メッセージ」は互いに分離していると思われるかもしれませんが、TCP やパイプのようなバイト ストリームはそうではありません。

エコー クライアントとサーバーのペアを考えてみましょう。クライアントは文字列を送信し、サーバーはそれを受信して​​すぐに送り返します。クライアントが「Hello」、「Hello」、「返事は?」と送信したとします。

バイト ストリーム プロトコルを使用すると、サーバーは「Hell」、「oHelloHow」、および「about an answer?」として受信できます。またはより現実的に「こんにちはこんにちは答えはどうですか?」. サーバーは、メッセージの境界がどこにあるのかわかりません。

古いトリックは、メッセージの長さを または に制限し、メッセージの長CHAR_MAXさを最初にまたはUINT_MAXで送信することに同意することです。したがって、受信側の場合は、最初にメッセージの長さを読み取る必要があります。これは、一度に 1 つのスレッドだけがメッセージの読み取りを行う必要があることも意味します。charuint

UDP やメッセージ キューなどの個別のプロトコルでは、この問題を心配する必要はありませんが、ファイルや stdin/out のように動作するため、プログラムでバイト ストリームを処理する方が簡単です。

于 2009-01-01T06:09:13.500 に答える
17

共有メモリは、その上に独自の通信スキームを構築するため、最も効率的ですが、多くの注意と同期が必要です。共有メモリを他のマシンに分散するためのソリューションも利用できます。

最近ではソケットが最も移植性がありますが、パイプよりも多くのオーバーヘッドが必要です。ソケットをローカルまたはネットワーク上で透過的に使用できることは、大きな利点です。

メッセージ キューとシグナルは、ハード リアルタイム アプリケーションには最適ですが、それほど柔軟ではありません。

これらのメソッドは、プロセス間の通信のために自然に作成されたものであり、プロセス内で複数のスレッドを使用すると、特にシグナルが複雑になる可能性があります。

于 2009-01-01T06:14:28.980 に答える
10

簡単なベンチマークの Web ページを次に示します: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

私が知る限り、それぞれに利点があります。

  • パイプ I/O は最速ですが、機能するには親子関係が必要です。
  • Sysv IPC には定義されたメッセージ境界があり、異種のプロセスをローカルに接続できます。
  • UNIX ソケットは、異種のプロセスをローカルに接続でき、帯域幅が高くなりますが、固有のメッセージ境界はありません。
  • TCP/IP ソケットは、ネットワーク経由であっても任意のプロセスに接続できますが、オーバーヘッドが高く、固有のメッセージ境界がありません。
于 2009-05-14T17:18:38.730 に答える
8

多くのライブラリが、あるタイプのものを別のタイプの上に実装していることは注目に値します。

共有メモリは恐ろしいsysv共有メモリ関数を使用する必要はありません-mmap()を使用する方がはるかにエレガントです(名前を付けたい場合はtmpfs / dev/shmにファイルをmmapします;必要な場合はmmap/dev /zero匿名で継承するためにプロセスを実行しないようにフォークしました)。そうは言っても、問題を回避するためにプロセスを同期する必要があります。通常は、他のIPCメカニズムのいくつかを使用して、共有メモリ領域へのアクセスの同期を行います。

于 2009-01-01T21:39:19.067 に答える