パイプ
親子プロセス間通信です。
「パイプ」はCoddyKit上の無料C Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。
パイプとは
パイプは、関連するプロセス間で一方向の通信を行うチャネルです。一方のプロセスがバイトを書き込み、もう一方のプロセスがそれを読み取ります。データのベルトコンベアのようなものです。
2 つのファイルディスクリプタ
pipe() 呼び出しは 2 要素の配列を設定します。fd[0] は読み取り側、fd[1] は書き込み側です。fd[1] に書き込んだデータは fd[0] から読み取れます。
#include <unistd.h>
#include <stdio.h>
int make_pipe(int fd[2]) {
if (pipe(fd) < 0) { perror("pipe"); return -1; }
/* fd[0] read end, fd[1] write end */
return 0;
}fork との組み合わせ
fork() の後、親プロセスと子プロセスはパイプのディスクリプタを共有します。これにより、親プロセスと子プロセスの一方が書き込み、もう一方が読み取る通信が可能になります。
使わない側を閉じる
各プロセスは使用しない側を close する必要があります。読み取り側は書き込み側を閉じ、書き込み側は読み取り側を閉じます。そうしないと、読み取り側はファイル終端を検出できません。
#include <unistd.h>
void parent_as_writer(int fd[2]) {
close(fd[0]); /* parent will not read */
write(fd[1], "hello", 5); /* parent writes */
close(fd[1]); /* signal EOF to reader */
}親子間通信の例
親プロセスがメッセージを書き込み、子プロセスがそれを読み取ります。それぞれ使用しない側を閉じます。
#include <unistd.h>
#include <stdio.h>
void demo(int fd[2]) {
if (fork() == 0) { /* child: reader */
close(fd[1]);
char buf[64];
ssize_t n = read(fd[0], buf, sizeof buf - 1);
buf[n] = 0;
printf("child got: %s\n", buf);
close(fd[0]);
} else { /* parent: writer */
close(fd[0]);
write(fd[1], "hi child", 8);
close(fd[1]);
}
}読み取りが EOF を返す場合
すべての書き込み側が閉じられると、read は0を返し、ファイル終端を示します。書き込み側が 1 つでも開いたままだと、読み取り側は追加データを待って永遠にブロックします。これはよくあるバグです。
パイプの容量とブロッキング
パイプには有限サイズのバッファがあります(多くの場合 64 KB)。バッファがいっぱいになると、読み取り側がデータを取り出すまで write はブロックします。空の場合、データが到着するまで read がブロックします。このフロー制御によって、2 つのプロセスが同期されます。
dup2 によるリダイレクト
dup2 を使うと、プロセスの stdin または stdout をパイプの一端に置き換えられます。これにより、シェルは cmd1 | cmd2 を実装し、一方のコマンドの出力を次のコマンドの入力に接続します。
#include <unistd.h>
void stdout_to_pipe(int fd[2]) {
close(fd[0]);
dup2(fd[1], STDOUT_FILENO); /* writes to stdout go into pipe */
close(fd[1]);
}名前付きパイプ(FIFO)
通常のパイプで接続できるのは、関連するプロセスだけです。名前付きパイプ(FIFO)は mkfifo で作成され、ファイルシステム上に存在するため、無関係なプロセスでもパスを指定して開き、通信できます。
#include <sys/stat.h>
int make_fifo(const char *path) {
return mkfifo(path, 0666); /* creates a FIFO file */
}SIGPIPE の危険性
読み取り側が閉じられたパイプに書き込むと SIGPIPE が発生し、デフォルトではプロセスが終了します。シグナルを無視するか、write から返される EPIPE エラーを確認してください。
パイプを使う場面
パイプは、親プロセスと子プロセスの間で単純な一方向ストリーミングを行う場合や、プログラムを連結する場合に適しています。双方向通信や無関係なプロセス間の通信には、FIFO、ソケット、共有メモリを検討してください。
理解度チェック
パイプについての理解度を確認しましょう。
まとめ
親子間通信にパイプを使う方法を学びました。
pipe()は fd[0](読み取り)と fd[1](書き込み)を返しますforkと組み合わせ、使わない側を閉じます- すべての書き込み側が閉じられると、EOF で read は 0 を返します
- FIFO は無関係なプロセスを接続します。SIGPIPE に注意してください
よくある質問
「パイプ」レッスンは無料ですか?
はい。「パイプ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。
「パイプ」で何を学びますか?
親子プロセス間通信です。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「パイプ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC Academyレッスンでコードを書いて実行できますか?
はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。