パイプ (コンピュータ)
UNIXにおけるパイプ(pipe)、もしくはパイプライン(pipeline)とは、複数のプログラムの入出力をつなぐための仕組みの一つである。このアイデアはUNIXやUNIXライクのOS以外にも、MS-DOS をはじめとする様々な OS やアプリケーションに、動作に多少の違いはあるものの受け継がれている。
目次 |
[編集] シェルからの使用
以下が典型的なパイプの利用例である。|(バーティカルバー) はシェルにパイプを指示する記号である。
grep 札幌市 Address.txt | a2ps | lpr
これは
- ファイル Address.txt から "札幌市" が含まれる行を出力し
- その出力を入力として受け取って a2ps コマンドを用いて整形し
- その出力を印刷する
といった処理を指示している。
パイプを使用する方法に対して、中間ファイルを利用する方法
grep 札幌市 Address.txt > sapporo.txt a2ps < sapporo.txt > print.ps lpr < print.ps
もあるが、パイプを利用する方法に比べ記述が冗長になるだけでなく、一般に動作が遅くなる。なぜなら、このように中間ファイルをつくる場合1 つ目のプログラムがすべてのデータを処理し終えるのを待って 2 つ目のプログラムが動かし、さらに2 つ目のプログラムが終了して初めて 3 つめのプログラムが動かす必要がある。しかしパイプを使えば、 3 つのプログラムをマルチタスクにより同時に動かし、I/Oなど時間がかかる処理の待ち時間を有効に使うことができる。さらに、逐次処理を行うために、データのサイズが大きい場合でも記憶領域を消費しない利点もある。また、データの受け渡しがメモリ上で行われるため、その点でも高速な処理が期待できる。
ただし、MS-DOS におけるパイプは、シングルタスク OS という制約のためパイプの動作は中間ファイルによってエミュレートされており、これらの利点はなく単なる略記法となっている。
UNIX の設計思想である、それぞれの役割に特化したプログラムを組み合わせ、複雑な機能を実現する(ツールキットアプローチ、分割統治法)として、パイプはその成功例であり、UNIX を利用する大きな魅力のひとつとなる。
[編集] プログラムによるパイプの作成
パイプはプログラムの制御の下で作成することもできる。pipe() システム・コールはオペレーティング・システムに新しいパイプ・オブジェクトを生成するように要求する。この結果、2つの新しいファイル記述子が開かれ、プロセスに渡される。つまり、読み取り専用のパイプの口と書き込み専用のパイプの口である。これらパイプの口は、シークができないことを除いて通常の匿名ファイルと同様に扱える。読み取り専用のパイプに対する読み出し命令は、書き込み専用のパイプに対してflushされるまでブロックされる。
デッドロックを避けたり並列処理をしたりするために、1つまたはそれ以上の新しいパイプをもつプロセスは、新しいプロセスを生成するのに、一般的に fork() を呼び出す。それぞれのプロセスは、データを作り出したり利用したりする前に、使われることのないパイプの口を閉じるだろう。または、最初のプロセスが単純に新しいスレッドを生成し、ただひとつのスレッドがひとつのパイプの口の利用を保証するようにするという方法もある。
[編集] プロセス間通信としてのパイプ
書き込み用のパイプと読み出し用のパイプを異なるプロセスが持つことで、ストリームを共有し、協調的な動作を行わせることができる。これはforkした親子関係にあるプロセス間のプロセス間通信で使われる。
さらに、パイプに名前をつけてアクセスすることができれば、親子関係にない任意のプロセス間で通信を行うことができる。このようなパイプを名前つきパイプ(named pipe)という。
POSIX(UNIX)では、名前つきパイプは mkfifo() または mknod() によって、ファイルシステムの名前空間に作成される。
Windowsでは、名前付きパイプを作成するサーバ側は、CreateNamedPipe() で「\\.\pipe\パイプ名」という形式の名前で作成すれば、パイプにつなぐクライアント側からファイルの読み書きと同じ操作で読み書きすることができる。また、Windows における匿名パイプは、ランダムな名前の名前付きパイプとして実装されている。
マシン間の通信にも名前付きパイプを利用することができるが、データを送るたびに、通信確認のためのデータが行き来するので、他のマシンと大量のデータを通信するときは、ソケットの方が高速である。ただし、マシン内のプロセス間通信の場合は、Windowsではカーネル内で動作するので名前付きパイプは高速である。