forkでCGIの重い処理
back
CGIから重い(処理に時間のかかる)処理を行うと、プログラムが終了するまで
ブラウザにはまったく表示が行われない。場合によってはタイムアウトや
Internal Server Error になる(かもしんない)。
そこで、fork をつかって、親プロセスではすぐにブラウザへ表示を返し終了し、
子プロセスで重たい処理を行う。
----
if($pid = fork) {
print "Content-type: text/plain\n\n";
print "done\n";
close(STDOUT);
exit;
}
else {
close STDOUT;
exit 0;
}
----
欠点は、クライアントからプログラムの終了がわからないこと。。。
そこで、fork の*後*に(というか、子プロセスで)ロックファイルを flock し、
プログラム終了にアンロックするようにし、親プロセスでは Location や
クライアントプルを使ってflock されたロックファイルを監視するプログラムへ
リダイレクトさせる。
※ その際、子プロセスが確実にロックできるように、sleep(1くらい) を入れる。
リダイレクト先では数秒毎に自分自身をロード(というかリンク)させ、そのたびに
ロックファイルが flock でロックされているかどうかをチェックし、
ロック解除(ロック取得成功) -> 重い処理のの結果を表示するページへジャンプ
ロック中(ロック取得失敗) -> x秒後に、再度自分へジャンプ
つー、処理にする。多分。
fork の後に flock するのは、前だと(親プロセスで flock すると)うまくいかないため
ファイルハンドルが子プロセスにもコピーされるとかそーいうことかな?(ソーゾー)
ちなみに Apache 1.3x はうまくいくけど、2.0x はプロセスツリー全体を見ているせいか、
親プロセスからのリダイレクトがうまくいかない。
そこで http ヘッダ
----
Connection: close
----
を出力して、Keep-Alive を切ってやるとうまくいく(みたい)
back