http://qs321.pair.com?node_id=329679

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

I've got a program that makes three separate system() calls to slow win32 shell commands:
# ... do stuff system("turtle.exe"); system("slug.bat"); system("inchworm.vbs"); # ... do more stuff
They all do different tasks and don't depend on each other, but the program must not proceed until all three have completed. Is there a way I can run them simultaneously, but keep system()'s block-until-finished behavior?

---
A fair fight is a sign of poor planning.

Replies are listed 'Best First'.
Re: Simultaneous system() calls
by flyingmoose (Priest) on Feb 17, 2004 at 19:32 UTC
    I like Proc::Background. Easy to use, allows you to wait on as many or as few as you like. Easily portable between Windows and UNIX-like systems. Also allows you to ask cool questions like "is this still running" or "is that still running...". Check it out.
Re: Simultaneous system() calls
by coreolyn (Parson) on Feb 17, 2004 at 19:20 UTC
Re: Simultaneous system() calls
by ysth (Canon) on Feb 17, 2004 at 19:58 UTC
    Start all three with fork/exec and then wait, or use a module. Perhaps looking at perldoc -q background would get you started.
Re: Simultaneous system() calls
by BrowserUk (Patriarch) on Feb 18, 2004 at 12:57 UTC

    This is very easy to do using threads.

    #! perl -slw use strict; use threads; my( @t, @r ); push @t, async { `dir /s c:` }; push @t, async { `dir /s d:` }; push @t, async { `dir /s p:` }; print "doing other stuff..." for 1 .. 10; # get and print the results. push @r, $_->join for @t; print for @r;

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!
Re: Simultaneous system() calls
by borisz (Canon) on Feb 17, 2004 at 19:36 UTC
    On Unix you might do this:
    system(qq{ turtle.exe & slug.bat & inchworm.vbs & wait });
    Boris
Re: Simultaneous system() calls
by halley (Prior) on Feb 17, 2004 at 21:07 UTC
    Windows shells have the start command to launch stuff in a variety of ways. It's a bit of extra overhead because it now requires an extra layer of command interpreter.

    For example, start /b turtle.exe will try to launch turtle.exe, and give you a success/fail result code. It will not wait for turtle.exe to finish, so any result code provided by turtle.exe is completely lost.

    my $command = "turtle.exe"; if ($^O =~ /win/i) { $command = "start /b $command" } else { $command = "$command &" } my $ret = system($command);
    However, there's no shell-accessible way of using Win32's WaitForMultipleObjects() API, which is what you'd need to launch A, B and C, and wait for all three to complete.

    --
    [ e d @ h a l l e y . c c ]

Re: Simultaneous system() calls
by Roger (Parson) on Feb 18, 2004 at 03:07 UTC
    One question - how many processors have you got in your box? If you have one processor only, I don't see how forking can improve the performance and make everything finish quicker.

      The answer to that depends very much on whether the programs in question use IO of some form.

      If they do, then one program can be utilising the processor whilst others are waiting for IO to complete.

      The time between clicking the link in your browser and the page starting to render on your screen. 2 to 10 seconds depending, is cpu dead-time that can be utilised by other programs. It's the extreme example, but even the delay on reading from a file--moving the head to the right track and then waiting for the disk to rotate into the right place--is often several hundreds or thousands of clock cycles that can be utilised by other processes. Caching complicates things of course.

      In this particular case, the processes I'm launching are network processes. They send a request to a remote server and then wait for a response. The response might take as long as an hour to come, but there's no processing being done locally while this happens. So launching them in parallel can shave off as much as two hours from runtime.

      ---
      A fair fight is a sign of poor planning.

Re: Simultaneous system() calls
by tcf22 (Priest) on Feb 17, 2004 at 19:02 UTC
    Depending on your version of perl, you could use ithreads. They are supported on newer versions of perl. Not sure what version they were implemented.

    - Tom