title: Forking child processes on file system events in perl
body: <p>I have a daemon process written in Perl that uses Inotify2 to watch directories for incoming files. On arrival of each file, the daemon will fork a child process. Now, it seems too many files are arriving at the same time (hence too many forks), because I got this error in my log file:</p>
  
  <pre><code>Cannot allocate memory at notifyd.pl line ...
  </code></pre>
  
  <p>which is the result of fork().</p>
  
  <p>Basically I have the following code:</p>
  
  <pre><code>    my $inotify = new Linux::Inotify2() or die($!);
  
      foreach my $k (@PATHS) {
          $inotify-&gt;watch($k,
  IN_MOVE_SELF|IN_DELETE_SELF|IN_CLOSE_WRITE, \&amp;watcher) or die($!);
      }
  
      $inotify-&gt;blocking(1) or die($!);
  
      for(;;) {
          $inotify-&gt;poll() or die($!);
      }
  </code></pre>
  
  <p>with the watcher function doing fork and then execv:</p>
  
  <pre><code>sub watcher {
          my $e = shift;
          my $pid = fork();
          if(!defined $pid) {
              print "[ERROR]", $!;
          }
          elsif($pid == 0) {
              my @args = ($e-&gt;fullname, $e-&gt;mask);
              exec($childprocess, @args) or die($!);
          }
  }
  </code></pre>
  
  <p>I cannot afford to miss events by not forking a process.</p>
  
  <p>Does anyone have suggestions how I can improve this and make sure fork will not fail?</p>
  
  <hr>
  
  <p>Edit: it seems like the child processes were becoming zombies once they exited since the daemon would not respond to SIGCHLD. So a lot of zombie child processes could have been the reason why fork() failed. The daemon now does    <code>$SIG{CHLD} = 'IGNORE';</code> before forking.</p>