wiki:Dev/Perl

Version 3 (modified by mitty, 14 years ago) (diff)

--

fork child process on CGI

  • sample code
    • Apache2 mpm-worker + Perl 5.10 on x64
      #! /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
      #! /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 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] <defunct>
        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 Tips (CGI, Perl, Unix and etc.))。