C99で複数のプロセスの間で通信をしたい!パイプを使いましょう。

子プロセスの準備

親から子プロセスへの出力用にファイルディスクリプタを準備します。

// N = num of child processes

// 親プロセスの入力用のファイルディスクリプタ
int fdOut[2 * N];

// 親プロセスの出力用ファイルディスクリプタ
int fdIn[2 * N];

パイプを作る。

for (int i = 0; i < N; i++) {
    pipe(&fdOut[2*i]);
    pipe(&fdIn[2*i]);
}

各子プロセスを作る。dup2を使って子プロセスの標準出力、標準入力を親プロセスにつなげます。

// does not check for errors

for (int i = 0; i < N; ++i) {
    if (!fork()) {
        // 子プロセスのstdoutを入力用パイプにつなぐ
        dup2(fdIn[i + 1], 1);
        // 子プロセスのstdoutを入力用パイプにつなぐ
        dup2(fdOut[i], 0);

        // 違うプログラマを立ち上げる
        execvp(executableLocation, argArray);
    }
}

これで子プロセスの準備は完了。

子プロセスへ出力

親から子プロセスへ文字列を送る。

// childNumber = n番目の子プロセス

char* string = "Hello World";

write(fdOut[childNumber * 2 + 1], string, sizeof(string));

もしくは、ファイルディスクリプタをファイルポインタとして開いてf系関数を使うことができます。

FILE *file = fdopen(fdOut[childNumber * 2 + 1], "w");

fprintf(file, "Hello World");

fclose(file);

子プロセスは標準入力が親プロセスとつながってるので、fgetsを使って入力文字列を受け取ることができます。

char *string = malloc(sizeof(char) * 128);

fgets(string, 128, stdin);

子プロセスから入力

子から親プロセスへ文字列を送る。子プロセスはstdoutが親プロセスとつながってるのでfprintで簡単に送れます。

fprint("Bye World");

親プロセスは以下のように子プロセスから受け取ります。

char* string = malloc(sizeof(char) * 128);
read(fdIn[player * 2], string, sizeof(string));

もしくは上記と同じようにファイルポインタとして開いて扱うことができます。

Tags:

Categories:

Updated: