perl background process

16,865

Solution 1

There are many problems with your script. Always:

use strict;
use warnings;

localising special variables is a good practice. Only a variable containing the special value undef returns false for defined. So, every other value (even a 0; which is the case here) returns true for defined. In the other script, the shebang is wrong.

#!/usr/bin/perl

use strict;
use warnings;

local $| = 1;

print "Before the child process\n";

unless (fork) {
    system("perl testing.pl");
    exit;
}

print "Before wait command\n";
wait;
print "After 20 secs of waiting\n";

Solution 2

The “Background Processes” section of the perlipc documentation reads

You can run a command in the background with:

system("cmd &");

The command’s STDOUT and STDERR (and possibly STDIN, depending on your shell) will be the same as the parent’s. You won't need to catch SIGCHLD because of the double-fork taking place; see below for details.

Adding an ampersand to the argument to system in your program can vastly simplify your main program.

#! /usr/bin/env perl

print "before the child process\n";

system("perl testing.pl &") == 0
  or die "$0: perl exited " . ($? >> 8);

print "before wait command\n";

wait;
die "$0: wait: $!" if $? == -1;

print "after 20 secs of waiting\n";

Solution 3

fork return value handling is a bit tricky, indeed. Recent article by Aristotle features a nice and concise forking idiom, which, in your case, looks like:

#!/usr/bin/env perl
use 5.010000;
use strict;
use warnings qw(all);

say 'before the child process';
given (fork) {
    when (undef) { die "couldn't fork: $!" }
    when (0) {
        exec $^X => 'testing.pl';
    } default {
        my $pid = $_;
        say 'before wait command';
        waitpid $pid, 0;
        say 'after 20 secs of waiting';
    }
}

Pay attention to exec $^X => '...' line: the $^X variable holds the full path to the current Perl executable, so the "right Perl version" will be guaranteed. Also, system call is pointless when you're pre-forking.

Share:
16,865
dreamer
Author by

dreamer

Updated on June 11, 2022

Comments

  • dreamer
    dreamer almost 2 years

    I am trying to run a background process in perl. I create a child process, which is used to call another perl script. I want to run few lines of code parallely with this child process. And after the child process is done.I want to print a line of code.

    Main script

    #!/usr/bin/perl
    
    $|=1;
    
    print "before the child process\n";
    
    my $pid = fork();
    
    if (defined $pid)
    {
        system("perl testing.pl");
    }
    
    print "before wait command\n";
    
    wait();
    
    print "after 20 secs of waiting\n";
    

    testing.pl

    #!/usr/bin/perl
    
    print "inside testing\n";
    
    sleep(20);
    

    Expected output

    before the child process
    before wait command
    (should wait for 20 secs and then print)
    after 20 secs of waiting
  • dreamer
    dreamer over 11 years
    i missed that part by mistake, i have included that in the code
  • ikegami
    ikegami over 11 years
    @dreamer, Greg Bacon was suggesting that as an alternative to using fork.