191 likes | 370 Views
パイプライン通信. 標準入出力とパイプライン シェルとパイプライン パイプによるプロセス間通信の仕組み pipe システム・コール pipe システム・コールとプロセス間通信 pipe システム・コールと、ファイル識別子 パイプ read/write プログラミング パイプライン通信プログラミング コマンドパイプライン型通信プログラミング dup シス テム・コール dup シス テム・コールと、ファイル識別子 パイプ dupe プログラミング. cmd < file file を cmd の標準入力にする 標準入力 キーボード ファイル
E N D
パイプライン通信 • 標準入出力とパイプライン • シェルとパイプライン • パイプによるプロセス間通信の仕組み • pipeシステム・コール • pipeシステム・コールとプロセス間通信 • pipeシステム・コールと、ファイル識別子 • パイプread/writeプログラミング • パイプライン通信プログラミング • コマンドパイプライン型通信プログラミング • dupシス テム・コール • dupシス テム・コールと、ファイル識別子 • パイプdupeプログラミング
cmd < file fileをcmdの標準入力にする 標準入力 キーボード ファイル cmd > file cmdの標準出力をfileにする 標準出力 ディスプレイ ファイル |: パイプライン (前のコマンドの標準出力を後のコマンドの標準入力にする) 標準入出力とパイプライン $ cat > input ooki oida okajima $ tr o i < input iiki iida ikajima $ tr o i < input > output $ cat output iiki iida ikajima $ tr o i < input | sort > output $ cat output iida iiki ikajima $
シェルとパイプライン echo | tr • シェルで、次のようなプログラムを動かすこと考える。 • % echo "hello,world" | tr '[a-z]' '[A-Z]' • HELLO,WORLD • % • この例では、echoのプロセスと、trのプロセスは、パイプで接続されている。 • パイプは、open() したファイルと同じようにread() したり write() したり することがでる。 • しかし実際には、ファイルではなく、プロセスとプロセスが データを交換する仕組(プロセス間通信の仕組)の1つである。 • 片方のプロセ スが write() したデータを、もう片方のプロセスがread() できる。 write() read()
パイプによるプロセス間通信の仕組み echo | tr • パイプにより提供されるプロセス間通信のサービスは、 (単方向の)ストリームとも呼ばれる。 • FIFO (First In, First Out)や Queue (待ち行列) と呼ばれることもある。 • パイプは、内部的には、8k バイト程度のバッファ(メモリ)がオペレーティング・システ ムのカーネルにある。 • バッファが一杯になると、書込み側のプロセスは write() で止まる(write() システムコールの呼び出しが元にもどらない。) • バッファが空だと、read() で止まる。 • 全部の書込み側の口が close() されると、read() で EOF が返る。 write() read() FIFO (First In, First Out) Queue
パイプを作るには、pipe() システム・コールを使う。 1つのパイプに対して、2つのファイル記述子(読込み用と書込み用)が返される。 インクルードファイル #include <unistd.h> 書式 int pipe(int filedes[2]); 戻値 成功時 0 失敗時 -1 使用例 int fd[2]; pipe(fd); pipeシステム・コール プロセス pipe(fd); fd[0] fd[0] = 3 fd[1] = 4 fd[1] パイプ バッファ read用 write用
pipeシステム・コールと、プロセス間通信 プロセスA pipe(fd); プロセスB pipe(fd); read用 read用 write用 write用 fd[0] fd[1] fd[0] fd[1] パイプバッファ
pipeシステム・コールと、ファイル識別子(1/3)pipeシステム・コールと、ファイル識別子(1/3)
pipeシステム・コールと、ファイル識別子(2/3)pipeシステム・コールと、ファイル識別子(2/3)
pipeシステム・コールと、ファイル識別子(3/3)pipeシステム・コールと、ファイル識別子(3/3)
パイプread/write (1/2) プロセス pipe(fd); fd[0] fd[0] = 3 fd[1] = 4 fd[1] パイプ バッファ read用 write用
パイプread/write (2/2) pipe-self.c
パイプライン通信 (1/2) プロセスA pipe(fd); プロセスB pipe(fd); read用 read用 write用 write用 fd[0] fd[1] fd[0] fd[1] パイプバッファ
パイプライン通信 (2/2) pipe-processes.c • 親プロセスは、パイプの読込み側(fildes[0])を閉じる。 そして、文字列から1バイトずつ取り出し、0 が現れるまで、パイプの書込み側(fildes[1])に書込む。 • 子プロセスは、パイプの書込み側(fildes[1])を閉じる。 そしてパイプの読込み側(fildes[0])から1バイト取り出す。これをtoupper() で大文字に変換して、標準出力(1)に書き出す。
コマンド型パイプライン通信 (1/3) プロセスA pipe(fd); プロセスB pipe(fd); read用 read用 write用 write用 fd[0] fd[1] fd[0] fd[1] パイプバッファ
コマンド型パイプライン通信 (2/3) parent.c • 親プロセス • パイプラインを生成 • 標準入力から数字を入力 • 子プロセスchildを生成 • パイプラインに数字を書込む • 子プロセス終了後パイプラインを読む • 読み出した数値を出力
コマンド型パイプライン通信 (3/3) child.c • 子プロセス • 引数からファイルディスクリプタを得る • パイプラインから数字を読む • 数字を2乗する • 2乗した結果をパイプラインに書き込む $ gcc -o parent parent.c $ gcc -o child child.c $ ./parent 512 512 x 512 = 262144 $
dupeシステム・コール • pipe() システム・コールで作られたファイル記述子は、しばしば dup() シス テム・コールで、0, 1 に変えられる。 • dup() システム・コールは、ファイル記述子を コピーするものである。 • dup() システム・コールは、ファイル記述子を、小さい数字から探していくので、たとえば close(0) の直後に dup(fd) すると、fd が 0 にコピーされる。 標準出力をパイプに切替 標準入力をパイプに切替 close( 1 ); dup( fildes[1] ); close( 0 ); dup( fildes[0] );
dupeシステム・コールと、ファイル識別子 標準出力をパイプに切替 標準入力をパイプに切替
パイプdupeプログラミング pipe-dupe-processes.c