fork関数 - プロセスを分岐する
fork関数を使用するとプロセスをふたつに分岐することができます。分岐したひとつのプロセスは親プロセス、もうひとつのプロセスは子プロセスになります。
fork関数
fork関数は引数をとりません。戻り値は分岐したプロセスが親プロセスの場合は、分岐した子プロセスのプロセスIDになります。子プロセスの場合は、0になります。forkが失敗した場合はundefが返ります。
my $pid = fork;
forkの戻り値を考慮する
親プロセスの場合、子プロセスの場合、forkが失敗した場合の3通りについて考える必要があります。
my $pid = fork; # forkが失敗した場合 die "Cannot fork: $!" unless defined $pid; if ($pid) { # 親プロセスの場合($pid に子プロセスのプロセスIDが代入されている) } else { # 子プロセスの場合$pid に0が代入されている }
forkが行っていること
forkが行うことは自分のプロセスのコピーです。自分自身のプロセスのコピーですから、それまでに使用していた変数は親プロセスでも子プロセスでも使用することができます。forkした後に変数に変更を加えた場合は、それぞれのプロセスだけで反映され、互いに影響を与えることはありません。
プロセス間通信については「Perlで「プロセス間通信」を行う」をご覧ください。
forkの使い道
1. 並列で処理を行う
forkを行えば並列で処理を行うことができます。シングルタスクでは性能が満たせない場合に利用することがあります。
2. 役割を分担する
ある手の場面においてひとつのプロセスがすべてを担当するよりも、プロセスを分岐させてそれぞれのプロセスが専門に行ったほうが記述が簡潔になることがあります。
3. 複数のプロセスを管理する
fork-execというテクニックを使用すると、分岐させた子プロセスをまったく異なるプロセスに置き換えることができます。たとえば、CPUやメモリの使用状況をみるvmstatというプロセスに置き換えることができます。親プロセスは子プロセスのプロセスIDを知っているので、親プロセスを制御を通じて、子プロセスを制御することができます。
forkのサンプルコード
use strict; use warnings; my $pid = fork; die "Cannot fork: $!" unless defined $pid; if ($pid) { print "親プロセス(子プロセスID: $pid)\n"; } else { print "子プロセス\n"; }
実行結果
分岐してそれぞれがprint文を実行していることがわかります。(Fedora7確認)
親プロセス( 子プロセスID: 25229 ) 子プロセス
Windowsでの注意
fork関数はWindowsでも実行することができますが、Windowsのfork関数はスレッドを使って擬似的に実現しているため本当のforkとは異なります。