名前付きパイプについて最近読んだのですが、なぜ存在するのか理解できませんでした。
名前付きパイプを使用すると、ファイルを使用するよりも時間がかかりません。
これはなぜですか?
名前付きパイプもメモリに保存する必要があります(ファイルと同様にスワップすることもできます)。
私が見る限り、ファイルと同様に、現在のディレクトリによって参照されるiノードを取得する必要があります。また、ファイルと同様に、プログラマーによって削除する必要があります。
では、利点はどこにあるのでしょうか?
名前付きパイプについて最近読んだのですが、なぜ存在するのか理解できませんでした。
名前付きパイプを使用すると、ファイルを使用するよりも時間がかかりません。
これはなぜですか?
名前付きパイプもメモリに保存する必要があります(ファイルと同様にスワップすることもできます)。
私が見る限り、ファイルと同様に、現在のディレクトリによって参照されるiノードを取得する必要があります。また、ファイルと同様に、プログラマーによって削除する必要があります。
では、利点はどこにあるのでしょうか?
回答:
Linuxのほとんどすべてはファイルと見なすことができますが、通常のファイルと名前付きパイプの主な違いは、名前付きパイプがファイルシステムに内容を持たないファイルの特別なインスタンスであることです。
ここからの引用ですman fifo
:
FIFO特殊ファイル(名前付きパイプ)は、ファイルシステムの一部としてアクセスされることを除いて、パイプに似ています。読み取りまたは書き込みのために複数のプロセスで開くことができます。プロセスがFIFOを介してデータを交換する場合、カーネルはすべてのデータをファイルシステムに書き込むことなく内部的に渡します。したがって、FIFO特殊ファイルにはファイルシステム上のコンテンツがありません。ファイルシステムエントリは単に参照ポイントとして機能するため、プロセスはファイルシステム内の名前を使用してパイプにアクセスできます。
カーネルは、少なくとも1つのプロセスによって開かれた各FIFO特殊ファイルに対して正確に1つのパイプオブジェクトを維持します。データを渡す前に、FIFOを両端で開く(読み取りと書き込み)必要があります。通常、もう一方の端も開かれるまでFIFOブロックを開きます。
したがって、実際には、名前付きパイプは、何らかのプロセスが読み取りと書き込みを行うまで何もしません。ハードディスク上のスペースを必要とせず(メタ情報の少しを除く)、CPUを使用しません。
これを行うことで確認できます:
名前付きパイプを作成する
$ mkfifo /tmp/testpipe
たとえばのディレクトリに移動し/home/user/Documents
、名前付きパイプを使用してその中のすべてをgzipします。
$ cd /home/user/Documents
$ tar cvf - . | gzip > /tmp/testpipe &
[1] 28584
ここで、gzipプロセスのPIDが表示されます。この例では、28584でした。
次に、このPIDが何をしているかを確認します
$ ps u -P 28584
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
c0rp 28584 0.0 0.0 29276 7800 pts/8 S 00:08 0:00 bash
リソースを使用していないことがわかります。CPU使用率0%、メモリ使用率0%。
ファイルスペースの使用に関する予測を確認する
$ du -h /tmp/testpipe
0 testpipe
そして再び0
、何も。必要に応じて、テストパイプを再び使用できます。
を使用して、gzipを強制終了することを忘れないでくださいkill -15 28584
。そして、次を使用して名前付きパイプを削除しますrm /tmp/testpipe
使用例
名前付きパイプを使用して、ほぼすべてをリダイレクトできます。例として、この1行のプロキシを見ることができます。
また、名前付きパイプの使用に関するもう1つのわかりやすい説明もあります。1つのサーバーで2つのプロセスを構成して、TCP / IPスタックの代わりに名前付きパイプを使用して通信できます。はるかに高速で、ネットワークリソースをロードしません。たとえば、Webサーバーは、localhost
アドレスを使用したりポートをリッスンしたりする代わりに、名前付きパイプを使用してデータベースと直接通信できます。
システムメモリを使用しないのは事実ですが、この例でCPUを使用しないのは、パイプを読み取らずにプロセスが待機しているためです。
次の例を検討してください。
mkfifo /tmp/testpipe
tar cvf - / | gzip > /tmp/testpipe
次に、新しいコンソールを開いて実行します:
watch -n 1 'ps u -P $(pidof tar)
そして、3番目のコンソールで:
cat /tmp/testpipe > /dev/null
watch cmd(2期目)を見ると、CPU消費量が増加していることがわかります。
名前付きパイプがI / Oを削除することで時間を大幅に節約できるユースケースを次に示します。
10GなどのBigFileがあるとします。
また、このBigFileを1Gの断片、BigFileSplit_01からBigFile_Split_10に分割しています。
今、BigFileSplit_05の正確性に疑問があります。
単純に、名前付きパイプがなければ、BigFileから新しいスプリットを作成して比較します。
dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05
名前付きパイプを使用すると
mkfifo BigFileSplitOrig_05
dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1 &
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05
それは一見大きな違いではないように見えるかもしれません...しかし、やがてその違いは大きくなります!
オプション1:
オプション2:
したがって、基本的に名前付きパイプを使用すると、1Gの読み取りと書き込みに加えて、ファイルシステムのクリーニングが節約されます(空のfifoノード以外はファイルシステムに何も書き込まないため)。
I / Oを行わないこと、特に書き込みを行わないことは、ディスクの摩耗を避けるためにも役立ちます。SSDを使用すると、セルが消滅する前に書き込み回数が制限されるため、さらに興味深いものになります。
(1)明らかに、たとえば/ tmpがRAM(tmpfs)にマウントされている場合、RAMに一時ファイルを作成することもできます。それでも、RAMディスクのサイズによって制限されますが、「名前付きパイプトリック」には制限がありません。
プログラムを静止させ、外部イベントの名前付きパイプを聞くことができます。外部イベントが発生するとすぐに(f.ex.いくつかの新しいデータの到着)、これは書き込みのためにパイプを開き、関連するイベントデータをパイプに書き込む他のプログラムによって検出される可能性があります。closeステートメントが発行されると、リスニングプログラムはreadステートメントを介してパイプを介してデータのストリームを受信し、取得したものを処理する準備が整います。コンテンツを読んだ後、パイプを閉じることを忘れないでください。リスニングプログラムは、同じまたは別の名前付きパイプを介して処理結果を返すこともできます。このようなプログラム間通信は、時には非常に便利です。