親プロセス・子プロセス間通信


個人的な授業のメモです

親プロセス·子プロセス間通信とは

 同じマシン上での、名前なしパイプを使ったプロセス間通信のことである。

そもそもプロセス通信とはなにか?

 プロセス(処理)同士が情報のやりとりを行うための通信のこと。
 クライアント・サーバーという言葉をよく耳にすると思う。これも実は、異なるマシン(コンピュータ)同士のプロセス間通信の事を指している場合がほとんどだ。

 

今回は同じマシン(コンピュター)同士が情報のやりとりを行う、親プロセス・子プロセス間通信を紹介する。

C言語をつかって親子プロセス間通信のプログラムをつくる

以下の図の動きをするプログラムをつくる

プログラムの流れ

実際のソースコード
pipe1.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main() {
  pid_t pid;
  char buf[256];
  int pp[2];

  // (1)パイプの作成
  pipe(pp);

  pid = fork(); // (2)子プロセスの生成

  // 子プロセスの動き
  if (pid == 0) {
    close(pp[0]); // (3)読み込みディスクリプタを閉じる
    printf("Message To Parent : ");
    fgets(buf, 256, stdin);
    write(pp[1], buf, strlen(buf) + 1); // (4)パイプへの書き込み
    close(pp[1]);
  }
  // 親プロセスの動き
  else {
    close(pp[1]); // (3)書き込みディスクリプタを閉じる
    read(pp[0], buf, 256); // (4)パイプから読み込み
    printf("Message From Child : %s", buf);
    close(pp[0]);
  }

  return 0;
}

※エラー処理は省略

実行結果
Message To Parent : Hello World! ←子プロセスで文字列を入力
Message From Child : Hello World! ← 子プロセスから送られてきた文字列を親プロセスで出力

無事、子プロセスから親プロセスへ文字列を送信することができた!

 ここでお気づきの人がいるかもしれない。パイプは一方通行だからこれだと親プロセスから子プロセスには文字列が送れないじゃないか、、、
しかし、パイプをもう1本増やすことで親プロセスから子プロセスへも文字列を送ることができる!

パイプ2本の親子プロセス間通信

パイプを2本にする事で双方向のデータ送信が可能になる。
親子プロセス間で、クライアント・サーバーにみたてて以下の図をプログラムにする。

ソースコード
pipe2.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
  pid_t pid ;
  char buffer[10], result[10];
  int pp[2], qq[2];
  int a , b, c;

  pipe(pp); // 親へデータを送るためのパイプ
  pipe(qq); // 計算結果を子に送るためのパイプ

  pid = fork();  // 親子のプロセスの生成

  // 子プロセスの動き
  if ( pid == 0 ) {
    close(pp[0]);
    close(qq[1]);

    // 1つ目の変数の代入とパイプへの書き込み
    printf("a = ");
    fgets(buffer, 10, stdin);
    write(pp[1], buffer, strlen(buffer)+1);

    // 2つ目の変数の代入とパイプへの書き込み
    printf("b = ");
    fgets(buffer, 10, stdin);
    write(pp[1], buffer, strlen(buffer)+1);

    // 計算結果を読み込む
    read(qq[0], result, 10);

    printf("a + b = %s\n", result);
    close(qq[0]);
    close(pp[1]);
  }
  // 親プロセスの動き
  else {
    close(qq[0]);
    close(pp[1]);

    // 1つ目の変数の読み込み
    read(pp[0], buffer, 256);
    a = atoi(buffer);

    // 2つ目の変数の読み込み
    read(pp[0], buffer, 256);
    b = atoi(buffer);

    c = a + b ; // 計算
    sprintf(buffer, "%d", c);

    // 計算結果をパイプへ書き込む
    write(qq[1], buffer, strlen(buffer)+1);

    close(pp[0]);
    close(qq[1]);
  }

  return 0;
}
実行結果
a = 5 ← 子プロセスで文字列を入力
b = 7 ← 子プロセスで文字列を入力
a + b = 12 ← 親プロセスでの計算結果を子プロセスが表示

無事、親プロセスから子プロセスへ計算結果が帰ってきた!

 

このようにC言語を使って親子プロセス間通信を確認することができる!