[[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.)])。 = making files with random name and random content = * [http://d.hatena.ne.jp/perlcodesample/20100413/1270894115 File::Temp - 一時ファイルの作成 / Perlモジュール徹底解説 - サンプルコードによるPerl入門] * [http://d.hatena.ne.jp/fbis/20080114/1200307393 ランダムな文字列を生成するString::Random - Unknown::Programming] * makerandom.pl {{{ #!perl #! /usr/bin/perl -w use strict; use warnings; use File::Temp qw(tempfile); use String::Random; my $filenum = $ARGV[0]; while ($filenum-- > 0) { my ($fh, $fname) = tempfile(DIR => '.'); my $length = int(rand(100)); print "making $fname ...\n"; print $fh String::Random->new->randregex("[A-Za-z0-9]{$length}"); } }}} = $line = <$hash{'filehandle'}>; # => GLOB = * [http://harapeko.asablo.jp/blog/2006/10/13/559447 山カッコ演算子にハッシュの要素を使用することはできない: 国民宿舎はらぺこ 大浴場] {{{ #!perl my %file = (); { open my $fh, '; # NG print $line; }}} * 実行結果 {{{ GLOB(0x161aa34)my %file = (); }}}