73


73

たくさんのIPCがUnix / Linuxで提供されています:パイプ、ソケット、共有メモリ、dbus、メッセージキュー…​

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

4 Answer


91


Unix IPC

これがビッグ7です。

  1. http://en.wikipedia.org/wiki/Pipe_%28Unix%29 [パイプ] +親/子として関連するプロセス間でのみ有用です。 http://linux.die.net/man/2/pipe [pipe(2)]とhttp://linux.die.net/man/2/fork [fork(2)]を呼び出してください。 単方向です。

  2. FIFO、または名前付きパイプ + 2つの無関係なプロセスは、プレーンパイプとは異なり、FIFOを使用できます。 http://linux.die.net/man/3/mkfifo [mkfifo(3)]を呼び出してください。 単方向です。

  3. Socketおよび Unixドメインソケット +双方向。 ネットワーク通信用ですが、ローカルでも使用できます。 異なるプロトコルに使用できます。 TCPにはメッセージ境界はありません。 http://linux.die.net/man/2/socket [socket(2)]を呼び出してください。

  4. http://en.wikipedia.org/wiki/Message_queue [メッセージキュー] + OSは個別のメッセージを維持します。 sys/msg.hを参照してください。

  5. Signal +シグナルは整数を別のプロセスに送信します。 マルチスレッドとうまく噛み合わない。 http://linux.die.net/man/2/kill [kill(2)]を呼び出してください。

  6. http://en.wikipedia.org/wiki/Semaphore_%28programming%29 [セマフォ] +バスルームを待っている人の列に似た、マルチプロセスまたはスレッドの同期メカニズム。 sys/sem.hを参照してください。

  7. http://en.wikipedia.org/wiki/Shared_memory [共有メモリ] +独自の同時実行制御を行います。 http://linux.die.net/man/2/shmget [shmget(2)]を呼び出してください。

メッセージ境界の問題

1つの方法を他の方法よりも選ぶときの1つの決定要因はメッセージ境界の問題です。 あなたは "メッセージ"がお互いから分離していると期待するかもしれませんが、それはTCPやPipeのようなバイトストリームのためではありません。

エコークライアントとサーバーのペアを考えます。 クライアントは文字列を送信し、サーバーはそれを受信して​​送信します。 クライアントが "こんにちは"、 "こんにちは"、および "回答はどうですか?"を送信したとします。

バイトストリームプロトコルでは、サーバーは "Hell"、 "oHelloHow"、および "about about answer?"として受信できます。もっと現実的に言うと "HelloHello答えについて?" サーバーは、メッセージの境界がどこにあるのかわかりません。

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

UDPやメッセージキューのような個別のプロトコルでは、この問題を心配する必要はありませんが、プログラム的にはバイトストリームはファイルや標準入出力のように振る舞うので扱いが簡単です。


15


共有メモリはその上に独自の通信方式を構築するので最も効率的ですが、それには多くの注意と同期が必要です。 他のマシンに共有メモリを分配するための解決策もあります。

ソケットは最近最もポータブルですが、パイプよりもオーバーヘッドが大きくなります。 ローカルまたはネットワークを介してソケットを透過的に使用する機能は、大きな利点です。

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

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


9


これは簡単なベンチマークのウェブページです:https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets

私が言える限りでは、それぞれに利点があります。

  • パイプI / Oが最速ですが、動作するには親子関係が必要です。

  • Sysv IPCには定義済みのメッセージ境界があり、異なるプロセスをローカルに接続できます。

  • UNIXソケットは、異なるプロセスをローカルに接続でき、帯域幅は広くなりますが、固有のメッセージ境界はありません。

  • TCP / IPソケットは、ネットワーク経由でも任意のプロセスに接続できますが、オーバーヘッドが大きく、固有のメッセージ境界はありません。


8


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

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