http://www.perlmonks.org?node_id=919238

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

I have some code that allows the user to start a process, but not to have to wait for the process to complete before moving on.

To do this a fork is used, and close STDOUT; invoked before the long process commences

This has been working fine but recently the process has started to hang, as though the close STDOUT; is being ignored. Can anyone suggest what might be going wrong, or if there is another way of starting the process then letting it run in the background?

my $pid; if ($pid = fork) { print qq~<response type="4" status="1">~; print qq~ </response>\n~; } elsif (defined $pid) { close STDOUT; #exit; my $myba = mybaapp->new(); my $linkbase = $myba->mob2myba($url); $myba->sendinfo($smsfrurl); exit; } else { die "Major error: $!"; } #end fork

Replies are listed 'Best First'.
Re: fork question
by zentara (Archbishop) on Aug 08, 2011 at 15:02 UTC
    Proc::Background ?
    #!/usr/bin/perl # Proc::Background is much more readable than fork and exec. # Plus, it works on Windows too -- fork tends not to work well there. use Proc::Background; my $proc; my @commands=($cmd1,$cmd2); foreach my $foo (@commands) { $proc = Proc::Background->new($foo); }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      Thank you - this looks promising. I shall investigate!
Re: fork question
by Perlbotics (Archbishop) on Aug 08, 2011 at 15:04 UTC

    Maybe you take STDOUT away too early (buffering and race condition) ?

    Does this work?
    my $pid; if ($pid = fork) { local $| = 1; # patch1 print qq~<response type="4" status="1">~; print qq~ </response>\n~; } elsif (defined $pid) { sleep 1; # patch2 close STDOUT; #exit; my $myba = mybaapp->new(); my $linkbase = $myba->mob2myba($url); $myba->sendinfo($smsfrurl); exit; } else { die "Major error: $!"; } #end fork
    Update: Ahhh, brainglitch. Forget this!
    Some more things to check: Did you update any modules recently? Does mybaapp use I/O (STDOUT)? What do you mean by ignored? Does the child still print something to STDOUT? Does it work if you do not close STDOUT? Did you use warnings;? Any warnings seen (e.g. print() on closed filehandle STDOUT at xxx line yyy.)? Any signals caught (SIGPIPE, SIGCHLD, etc.)? What does the main program (parent) do? Does it wait?

      Hi, thanks for your reply. Unfortunately that doesn't seem to be the problem - even increasing sleep to 5 just keeps hanging

        You might have better luck trying to close or permanently redirect all filehandles. It may even be that you need to close ALL filehandles which you might have open. Maybe in the intervening time since the script was working, and not, you added some code elsewhere which opened some filehandles? See how to close all files
        close(STDOUT);close(STDIN);close(STDERR);
        or even
        open STDIN, "</dev/null"; open STDOUT, ">/dev/null"; open( STDERR, ">>/path/to/logfile");

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh