tags:

views:

111

answers:

3

I'm doing a bunch of system calls that I want to run in parallel:

system(" sleep 5 && echo step 1 done &");
system(" sleep 3 && echo step 2 done &");
system(" sleep 7 && echo step 3 done &");

// block here

How can I block the program flow until all the system calls are finished?

+4  A: 

Fork a child process to perform each job, and in the parent, wait for those processes to finish before exiting.

See perldoc perlfork, perldoc -f fork and perldoc -f waitpid.

(The exact code for this is left as an exercise for the reader -- everyone should have to write this from scratch at least once, to understand the details involved. There are lots of examples on this site as well.)

Ether
+1  A: 

what about running each one of the system call from a different thread and join on the threads

jojo
Threads are rarely a good idea in general, IME. And they're an especially ungood idea in Perl, whose threads are a gigantic pain in the ass. The `fork` solution is probably best.
friedo
The perl version we're using for my project doesn't have "thread"support and I don't use perl much so I'm not going to try to migrate our project. Thanks for the suggestion though.
Ross Rogers
+6  A: 

The easiest way to do this is probably to fork a new child process for each system call, and then wait for them to finish. Here's a simplified example:

my @commands = ( "sleep 5 && echo step 1 done",
                 "sleep 3 && echo step 2 done",
                 "sleep 7 && echo step 3 done" );

my @pids;
foreach my $cmd( @commands ) {
    my $pid = fork;
    if ( $pid ) {
        # parent process
        push @pids, $pid;
        next;
    }

    # now we're in the child
    system( $cmd );
    exit;            # terminate the child
}

wait for @pids;   # wait for each child to terminate

print "all done.\n";
friedo
Perfect. I know I should suffer more and synthesize the answer on my own... but my perl is pretty rusty. Thank you for this snippet.
Ross Rogers
It would bloat the example so I don't want to complain much, but if `fork` fails, it returns `undef` which is false, and then this code does the wrong thing. Also, I'd vote for using `exec` instead of `system+exit` - Perl's `exec` does allow you to give it a full string for the shell such as these.
ephemient