ファイルの代わりに名前付きパイプを使用する理由


42

名前付きパイプについて最近読んだのですが、なぜ存在するのか理解できませんでした。
名前付きパイプを使用すると、ファイルを使用するよりも時間がかかりません。

これはなぜですか?
名前付きパイプもメモリに保存する必要があります(ファイルと同様にスワップすることもできます)。
私が見る限り、ファイルと同様に、現在のディレクトリによって参照されるiノードを取得する必要があります。また、ファイルと同様に、プログラマーによって削除する必要があります。

では、利点はどこにあるのでしょうか?


これは教室の課題の一部ではありませんか?
don.joey

6
いや...実際、私はこの質問を見つけたとき、いくつかの講義ノートを見ていましたが、答えられませんでした...そしてそれが課題だった場合、それがどのように関連するかわかりません...それは好きではありません私はそれを見つけるまで答えを検索しません
user3122885 14

回答:


41

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アドレスを使用したりポートをリッスンしたりする代わりに、名前付きパイプを使用してデータベースと直接通信できます。


14

システムメモリを使用しないのは事実ですが、この例で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消費量が増加していることがわかります。


1
この答えは、についてですc0rpの答え
wjandrea

2

名前付きパイプが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:

  • dd:1Gの読み取り/ 1Gの書き込み (1)
  • diff:2Gを読み取ります
  • rm:割り当てられたクラスターの解放/ディレクトリエントリの削除

オプション2:

  • dd:何もない!(名前付きパイプに移動します)
  • diff:2Gを読み取ります
  • rm:管理する割り当てられたクラスターがありません(実際にはファイルシステムに何も書き込みませんでした)

したがって、基本的に名前付きパイプを使用すると、1Gの読み取りと書き込みに加えて、ファイルシステムのクリーニングが節約されます(空のfifoノード以外はファイルシステムに何も書き込まないため)。

I / Oを行わないこと、特に書き込みを行わないことは、ディスクの摩耗を避けるためにも役立ちます。SSDを使用すると、セルが消滅する前に書き込み回数が制限されるため、さらに興味深いものになります。

(1)明らかに、たとえば/ tmpがRAM(tmpfs)にマウントされている場合、RAMに一時ファイルを作成することもできます。それでも、RAMディスクのサイズによって制限されますが、「名前付きパイプトリック」には制限がありません。


1

プログラムを静止させ、外部イベントの名前付きパイプを聞くことができます。外部イベントが発生するとすぐに(f.ex.いくつかの新しいデータの到着)、これは書き込みのためにパイプを開き、関連するイベントデータをパイプに書き込む他のプログラムによって検出される可能性があります。closeステートメントが発行されると、リスニングプログラムはreadステートメントを介してパイプを介してデータのストリームを受信し、取得したものを処理する準備が整います。コンテンツを読んだ後、パイプを閉じることを忘れないでください。リスニングプログラムは、同じまたは別の名前付きパイプを介して処理結果を返すこともできます。このようなプログラム間通信は、時には非常に便利です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.