phonybone_monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello, perlmonks,

I am seeking advice on diagnosing a problem related to a Perl program (which I inherited) that makes use of fork(). The basic problem seems to be that some of the forked sub-processes immediately exit without doing any work. When those processes are reaped (with wait()), $? is set to 11, which I believe is the error code for "resource temporarily unavailable, try again". I am trying to determine which resource is unavailable. The environment is Linux/Centos 7

The basic structure of this program is as follows:

Here's a pseudo code outline (note: this won't actually re-create my problem, of course):

# Initialization # Read input file, calls to system('bowtie2', ...) and system('samtool +s', ...) use strict; use warnings; use Carp qw(confess); use Sys::Info::Device::CPU; use Sys::Info::Constants qw( :device_cpu ); my $info = Sys::Info->new; my $cpu = $info->device( CPU => {} ); my $nthreads = $cpu->count; print "$nthreads threads\n"; while ($nthreads--) { my $pid = fork; confess ("Can't fork: $!") unless defined $pid; if (! $pid) { print "child process: $$\n"; # this line never gets executed +by some of the children # Do a bunch of processing using intermediate files as input, usin +g Bio::DB::Sam->get_features_by_location() to access intermediate fil +es exit 0; } } # parent continues here: my $pid = 0; my $ok = 1; while ($pid != -1) { $pid = wait; last if $pid == -1; my $err=$?; if ($err) { print("one of the children died: pid=$pid, err=$err\n"); $ok = 0; } } if (! $ok) { confess "some child processes died."; } print "all done, yay\n";

In all of the processes, the line directly after the fork confess("Can't fork: $!") unless defined $fork; never gets executed. I infer that the fork itself did happen.

But some of the processes, depending on the input file, are reaped immediately, with $err=11 (EAGAIN). I surmise I am running short of some resource, but which one? I have increased the limits for the following resources to values (by editing /etc/security/limits.conf, and then rebooting) that I believe should be more than sufficient, to no avail:

I've also increased swap space via swap files.

Short or restructuring the code to use exec(), which I've considered, do any wise monks have suggestions as to:

My thanks for all answers, insights, and useful comments

Replies are listed 'Best First'.
Re: Trouble with fork()
by shmem (Chancellor) on May 22, 2017 at 21:16 UTC

    Hmm, interesting node, I thought, let's have a look, downloaded your sample, ran it as perl -c 1190887.pl and got this

    String found where operator expected at 1190887.pl line 24, near "conf +ess "some child processes died."" (Do you need to predeclare confess?) syntax error at 1190887.pl line 24, near "confess "some child processe +s died."" Missing right curly or square bracket at 1190887.pl line 26, at end of + line syntax error at 1190887.pl line 26, at EOF 1190887.pl had compilation errors.

    Please correct your posted code to the extent that it passes syntax checks and resembles what you are actually doing.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
A reply falls below the community's threshold of quality. You may see it by logging in.