wiki:Dev/Perl/example

Version 2 (modified by mitty, 13 years ago) (diff)

moved from ../

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.))。

making files with random name and random content

  • makerandom.pl
    #! /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