forkで時間のかかる処理をバックグランドで行い、ブラウザをすぐに解放させる方法。
#!/usr/local/bin/perl
# バッファリング制御
$| = 1;
# HTMLヘッダー出力
print "Content-type: text/html; charset=EUC-JP\n\n";
print "<h3>fork()のテスト</h3>\n";
FORK: {
if( $pid = fork ) {
# 親プロセス--------------------------------------------
print "<p>親プロセスの処理</p>\n";
# 標準入力/標準出力/標準エラー出力をclose
# Apacheから終了ステータスが返りブラウザが解放される
close(STDIN);
close(STDOUT);
close(STDERR);
# 子プロセスの終了を待つ
wait;
} elsif (defined $pid) {
# 子プロセス---------------------------------------------
print "<p>子プロセスの処理</p>\n";
# 標準入力/標準出力/標準エラー出力をclose
# Apacheから終了ステータスが返りブラウザが解放される
close(STDIN);
close(STDOUT);
close(STDERR);
#####################################################
# ▼ 時間のかかる処理(ここから)
#####################################################
sleep(10);
#####################################################
# ▲ 時間のかかる処理(ここまで)
#####################################################
exit;
} elsif ( $! =~ /No more process/) {
# プロセスが多すぎる場合、時間を置いて再開
sleep 5;
redo FORK;
} else {
# 通常ここに来ることはない
die "Can't fork: $\n";
}
} # End Of Label:FORK
exit;
STDIN、STDOUT、STDERRのcloseですが、UNIX環境下ではSTDOUTのcloseだけでいい様です。Windows XP&ActivePerl5.8ではSTDOUTとSTDERRの二つで解放されました。
