[[PageOutline]] = fork child process on CGI = * [http://www.bioinfo.jp/tips.html Tips (CGI, Perl, Unix and etc.)] * [http://www.tohoho-web.com/lng/199910/99100140.htm CGI-Perlのforkで子供を置き去りにするには?] * [http://www.stackasterisk.jp/tech/program/perl04_02.jsp Perl第4回:PerlTips(バックグラウンドで処理を実行)] * sample code * Apache2 mpm-worker + Perl 5.10 on x64 {{{ #!perl #! /usr/bin/perl -w my $pid = fork; if (! defined $pid) { # cannot fork die("cannot fork: $!"); } if ($pid) { # parent process print "Content-type: text/html;\n\n"; # output something print "parent: $$ / child: $pid\n"; close(STDIN); close(STDOUT); exit; } else { # child proccess close(STDIN); close(STDOUT); # long long proccess ... sleep(60); } }}} * Apache2 mpm-prefork + Perl 5.10 on x64 {{{ #!perl #! /usr/bin/perl -w my $pid = fork; if (! defined $pid) { # cannot fork die("cannot fork: $!"); } if ($pid) { # parent process print "Content-type: text/html;\n\n"; print "parent: $$ / child: $pid\n"; } else { # child proccess close(STDOUT); sleep(60); } }}} * 子プロセスでclose(STDOUT)が必要とだけ書かれている文献が多いが、Apache2 mpm-worker環境では親子ともSTDINも閉じないと親プロセスは終了しなかった。 * しかし、テストのため一度mpm-preforkに切り替えた後、再度mpm-workerに戻した後は何故かpreforkと同じ挙動(STDINを閉じなくてもOK)を示すようになった。 * apache2 -V {{{ Server version: Apache/2.2.14 (Ubuntu) Server built: Apr 13 2010 20:22:19 Server's Module Magic Number: 20051115:23 Server loaded: APR 1.3.8, APR-Util 1.3.9 Compiled using: APR 1.3.8, APR-Util 1.3.9 Architecture: 64-bit Server MPM: Worker threaded: yes (fixed thread count) forked: yes (variable process count) }}} * Apache2 mpm-preforkでは子プロセスでclose(STDOUT)するだけで良かった。 * apache2 -V {{{ Server version: Apache/2.2.14 (Ubuntu) Server built: Apr 13 2010 20:21:26 Server's Module Magic Number: 20051115:23 Server loaded: APR 1.3.8, APR-Util 1.3.9 Compiled using: APR 1.3.8, APR-Util 1.3.9 Architecture: 64-bit Server MPM: Prefork threaded: no forked: yes (variable process count) }}} * 親プロセスについてはSTDIN/STDOUTを閉じた時点でhttpdからプロセスが終了させられるので(see [http://www.bioinfo.jp/tips.html Tips (CGI, Perl, Unix and etc.)])、exit前に何かの処理を行うことは出来ない。 * mpm-preforkでは子プロセスが終了するまで、親プロセスはゾンビとして残った。mpm-workerではそのようなことはない模様(こちらも、一度mpm-preforkに切り替えると、workerに戻してもゾンビが残るようになった)。 * ps aux | grep www-data {{{ www-data 3767 0.0 0.0 0 0 ? Z 15:28 0:00 [fork.cgi] www-data 3768 0.0 0.1 16700 668 ? S 15:28 0:00 /usr/bin/perl -w /var/www/archive/fork.cgi }}} * ただし、ゾンビとなった親プロセスは入出力がないため、しばらくするとhttpdによって殺される(see [http://www.bioinfo.jp/tips.html Tips (CGI, Perl, Unix and etc.)])。