第75章 fork()

目次

75.1. fork() を 2 回コールする
75.2. fork() を 3 回コールする
75.3. fork() を 4 回コールする

マルチタスク、マルチプロセスは Linux では fork() 関数を使うことで実現できます。

てよかですね…

fork() 関数を知っておいて貰わないと共有メモリーオブジェクトが何なのか説明になっちまいますんで、fork() の基本的な挙動をこの機会に説明させていただきます。

宣言は以下のようになります。

#include <sys/types.h>
#include <unistd.h>

pid_t fork(void);

 Linux のマニュアル読んで頂くと、この fork() 関数は子プロセス( child process )を生成する関数だと書いてあると思いますが、これだと抽象的過ぎますね。

 より具体的に言うと現在実行中のプロセスをそのまま一つコピーして fork() 関数を発行する行以降のソースコードを実行してくれる子プロセスを作ります。

 さらに fork() を実行して子プロセスを生成するプロセスは親プロセス( parent process )と呼ばれてます。

 戻り値型である pid_t はプロセス ID というプロセスを識別する整数型です。

 ちなみに fork() 関数が返すプロセス ID の 0 は処理が子プロセスにあることを意味します。

  0 以外のプロセス ID が親プロセス側で戻る ID となりますが、この親プロセスで返ってくるプロセス ID は子プロセスの ID となります。

 では親プロセス ID は何なの?

 処理中のプロセス ID と同じです。

 つまり親プロセスの ID は自明なので fork() で返さなくても良いってことです。

 ややこしいのでまとめますね。

 ついでに fork() 関数の概要についても、言葉が足りないと思うので繰り返しますね。

 fork() 関数をコールすると以下の 2 つのことがおきます。

 まあこの説明もまだ抽象的すぎるんで以下の実装コードで確認してみましょう。

main.c. 

  1 #include <unistd.h>
  2 #include <stdio.h>
  3
  4 int main()
  5 {
  6   pid_t pid;
  7   pid = fork();
  8   printf("%d\n",pid);
  9
 10   return 0;
 11 }

ビルドと実行結果. 

$ gcc main.c
$ ./a.out
9673
0

 このコードの出力を見ると、0 以外のプロセス ID は 1 個しかないので、子プロセスが 1 個生成されています。

 0 を出力しているのが子プロセスで、子プロセス の ID の 9673 を出力しているのが親プロセスですね。

 ではソースコードを見てみましょう。

  6   pid_t pid;

 pid はプロセス ID を保持するための変数です。

  7   pid = fork();

 fork() を実行して作ったプロセス ID は pid に代入されます。

 この行の段階で元からあるプロセスの仮想アドレス空間をコピーした子プロセスができます。

 したがって pid には親プロセスの pid と子プロセスの pid の 2 つがありますが、値は異なります。

 親プロセスで実行した fork() の返り値ことプロセス ID は子プロセスの ID となり、この場合では子プロセスの ID は 9673 となります。

  8   printf("%d\n",pid);

 子プロセスが出力する pid は 0 となります。

Copyright 2018-2019, by Masaki Komatsu