FIFOは名前付きパイプだと聞きました。そして、それらはまったく同じセマンティクスを持っています。一方、Unixドメインソケットはパイプに非常に似ていると思います(使用したことはありませんが)。だから、彼らはすべてLinuxカーネルの同じ実装を参照しているのだろうか。何か案が?
FIFOは名前付きパイプだと聞きました。そして、それらはまったく同じセマンティクスを持っています。一方、Unixドメインソケットはパイプに非常に似ていると思います(使用したことはありませんが)。だから、彼らはすべてLinuxカーネルの同じ実装を参照しているのだろうか。何か案が?
回答:
UNIXドメインソケットとFIFOは実装の一部を共有する場合がありますが、概念的には非常に異なります。FIFOは非常に低いレベルで機能します。1つのプロセスがバイトをパイプに書き込み、別のプロセスがパイプから読み取ります。UNIXドメインソケットは、TCP / IPソケットと同じ動作をします。
ソケットは双方向であり、多くのプロセスで同時に使用できます。プロセスは、同じソケットで多くの接続を受け入れ、同時に複数のクライアントに参加できます。カーネルは毎回新しいファイル記述子を配信するconnect(2)
かaccept(2)
、ソケットで呼び出されます。パケットは常に正しいプロセスに送られます。
FIFOでは、これは不可能です。双方向通信の場合、2つのFIFOが必要であり、クライアントごとに1組のFIFOが必要です。選択的な方法で書き込みまたは読み取りを行う方法はありません。通信するためのはるかに原始的な方法だからです。
匿名パイプとFIFOは非常に似ています。違いは、匿名パイプがファイルシステム上にファイルとして存在しないため、プロセスで処理できないopen(2)
ことです。別の方法で共有するプロセスで使用されます。プロセスがFIFOを開いてから、たとえばaを実行するとfork(2)
、その子はファイル記述子と、その中でもパイプを継承します。
UNIXドメインソケット、匿名パイプ、およびFIFOは、共有メモリセグメントを使用するという点で類似しています。実装の詳細は、システムによって異なりかもしれませんが、アイデアは常に同じです:二つの異なるプロセスのメモリマッピングでメモリの同じ部分を添付して、彼らがデータを共有しているために
(編集: 1つの明白な方法は、それを実装するだろうが、それはありますLinuxで実際に行われる方法ではなく、単純にバッファーにカーネルメモリを使用します。以下の@ tjb63による回答を参照してください)。
カーネルはシステムコールを処理し、メカニズムを抽象化します。
これに関する非常に良い議論がここにあります:http : //www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
私が見る限り、プレゼンテーションスライドとソース@ http://lxr.free-electrons.com/source/fs/pipe.cの両方から-fifoはパイプのラッパーとして実装されており、パイプ自体はpipefs仮想ファイルシステムを介して実装されます。
@lgeorget-パイプはリーダーとライター間のバッファにカーネルメモリを使用しているように見えます-それらは「共有メモリ」を使用せず、ユーザーとカーネルアドレススペース間でメモリをコピーします(たとえば、pipe_read
calls pipe_iov_copy_to_user
、which __copy_to_user_inatomic
(またはcopy_to_user
)) 。__copy_to_user_inatomic
呼び出しcopy_user_generic
、これはいくつかのASM実装の1つです。
「FIFO」と「名前付きパイプ」は同じものです。ただし、シェルがコマンドラインの2つのコマンド間の「パイプ」(|)を処理する方法とはまったく異なります。
名前付きパイプ(FIFO)は、2つのプログラムによって共有される単一の「ファイル」です。1つは書き込みを行い、もう1つは読み取りを行います...一方、ソケットは2つの「ファイル」間の「接続」です。ネットワークを使用し、別のコンピューター上にある-1つのプログラムが1つの「ファイル」に対して読み取り/書き込みを行い、別のプログラムがもう1つのファイルに対して読み取り/書き込みを行う...似ているとは思わない...一方では両方ソケットと名前付きパイプ-ファイル、デバイス、シンボリックリンク-はすべてiノードを使用し、それらはすべていくつかの一般的な機能(読み取りや書き込みなど)を実装します。
私はそうは思いませんジャスティン。間違っていないなら、おそらくそうかもしれませんが、FIFOはディスク上のファイルを使用し、Unixドメインソケットはカーネルメモリを使用すると思います。
また、Unixドメインソケットは双方向であると述べた上記のポスターへの追加として、SOCK_STREAMソケットを使用する場合にのみそうです。SOCK_DGRAM Unixドメインソケットは、実際には単方向であり、connect()を呼び出したコードからbind()を呼び出したコードにのみsend()できます。
もちろん、connect()を呼び出したコードはbind()を呼び出して独自のエンドポイントを作成する必要がありますが、それは質問とは関係ありません。
私の2セント... FIFOとUNIXソケットはどちらも双方向(類似)ですが、ソケットはスタートポロジを持ち、FIFOは単なるキューです(したがって互いに交換することはできません)、それらの実装は内部でコードを共有できます。
**
char * myfifo = "/tmp/myfifo";
mkfifo(myfifo, 0666);
fd = open(myfifo, O_RDWR); //so that you can read/write to it
...
write(fd, buff1, sizeof(buff1));
getchar();//wait till some one reds this and writes something else
int sz=read(fd, buff1, sizeof(buff1)); //read that something**