🐧 Linux 総合学習プラットフォーム
システムコール ・ 上級

パイプによるプロセス間通信(pipe / dup2)

シェルの | の裏側にあるpipe。片方向のデータ管を作り、forkした親子でファイルディスクリプタを引き継いで通信する。dup2で標準入出力に差し替える発想も見る。

シェルで `ls | wc -l` と書くと、ls の出力がそのまま wc へ流れる。この縦棒 | の正体がパイプだ。プロセス同士がデータを受け渡すための、片方向の管をカーネルが用意する。

🧩 読み口と書き口のペア

pipe を呼ぶと、ファイルディスクリプタが2つ返る。一方が読み込み専用、もう一方が書き込み専用で、片方に書いた内容がもう片方から読める。データはカーネル内のバッファを通るので、ファイルを介さずメモリ上でやり取りされる。

💡
ポイントEX: `int pipe(int filedes[2]);` を呼ぶと、`filedes[0]` が読み込み側、`filedes[1]` が書き込み側になる。書き込み側に write した内容が、読み込み側から read で取り出せる。

🧩 fork と組み合わせる

パイプが真価を発揮するのは fork との併用だ。pipe で管を作ってから fork すると、親子の両方が同じ読み口と書き口を引き継ぐ。あとは使わない側を close して、親が書いて子が読む(またはその逆)と決めれば、親子間の一方向通信になる。

💡
ポイントTIP: 使わない端は必ず close する。書き込み側を全員が閉じないと、読み込み側は「まだ書かれるかも」と待ち続けて終端(read が0を返す)にならない。開けっ放しがハングの典型原因になる。

🧩 dup2 で標準入出力に差し替える

シェルがコマンドをつなげられるのは、パイプの端を標準出力や標準入力に差し替えているからだ。この差し替えを行うのが dup2 で、あるディスクリプタの中身を別の番号(1なら標準出力、0なら標準入力)に複製する。

💡
ポイントEX: `dup2(filedes[1], 1);` とすると、以後その子プロセスの printf などの標準出力はパイプの書き込み側へ流れる。これを子側で行ってから exec すれば、コマンドは自分が pipe に書いていると意識せず動く。
💡
ポイントANALOGY: pipe は2つの部屋をつなぐ伝声管、fork は同じ管を持ったまま部屋が2つに分かれること、dup2 は「自分の口をその管の入口に固定する」作業。3つが揃って初めて `ls | wc` のような連結が成り立つ。

この項目に出てくる用語

pipeぱいぷ
プロセス間の片方向通信路を作るシステムコール。
dup2でゅーぷつー
ファイルディスクリプタを指定番号に複製するシステムコール。

▶ 学習アプリでこの続きを学ぶ・演習する