in reply to Re: Re: Re: How to multiprocess in Win32?
in thread How to multiprocess in Win32?

I've never had any difficulty getting Perl to crash when using the emulated fork under Win32. Even trivial programs will crash or just plain "act strange". It is so easy to get it to fail that I haven't even bothered filing a bug report (just picking which of dozens to send in first would be a problem).

As for multiprocessing, I've mostly replaced fork with:

if( @ARGV && $ARGV[0] eq "-child" ) { shift( @ARGV ); # child code here exit( 0 ); } # Am parent # ... system(1,$^X,$0,"-child",@ARGV); # run child # ...
in cases when I needed it.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re^2: How to multiprocess in Win32?
by wolfger (Deacon) on Oct 22, 2004 at 16:52 UTC
    Could you explain what is going on here a bit? I'm a novice Perl coder, and my first professional script needs to be modified to include a second fork... which, of course, kills me entirely on this blasted Win32 environment. I'm hesitant to use your workaround without understanding exactly what is going on, though.

    I need to spawn two children, each of which are non-perl exe files, and one of which may be killed and respawned multiple times over the life of the parent.

    --
    Believe nothing, no matter where you read it, or who said it - even if I have said it - unless it agrees with your own reason and your own common sense.
    (Buddha)

      You have a script, say 'util', and you kick it off by typing a command something like:

      $ util -x this that

      Which runs perl, telling it to run the util script with the three arguments you specified. So, this code gets run:

      if( @ARGV && $ARGV[0] eq "-child" ) { shift( @ARGV ); # child code here exit( 0 ); } # Am parent # ... system( 1, $^X, $0, "-child", @ARGV ); # run child # ...

      And @ARGV is set to ( '-x', 'this', 'that' ). So the first line checks @ARGV in a scalar context which gives us its number of elements, 3, which isn't 0 so it is true and we try the expression after the &&.

      $ARGV[0] is '-x', which isn't the same string as '-child' so the 'if' fails and the code in its block gets skipped.

      So system( 1, $^X, $0, "-child", @ARGV ); gets run. The '1' tells system to not wait for the command that it starts. This only works in OS/2 and Win32 (and probably still isn't documented).

      So the next argument says what program to run. $^X is the name of the file containing the Perl interpreter, something like '/usr/bin/perl' or just 'perl'. So the perl interpreter gets run in a new child process and we don't wait for it to finish.

      The first argument passed to perl says what script to run so we put $0 so the child process runs our same script (again).

      Next we pass in "-child" and our @ARGV and these end up in @ARGV in the child process.

      So when the above code gets run in the child process it is true that $ARGV[0] eq "-child" so the 'if' block gets run.

      shift( @ARGV ); # child code here exit( 0 );

      The shift removes the '-child' so that @ARGV is now the same as in the parent.

      The comment should be replaced with whatever code you want run in the child.

      And the exit prevents the rest of the code (meant for the parent in this example) being run in the child.

      So the effect is very much like fork.

      - tye        

        Thanks for the explanation! It looks like all I really need is that "1," in my system call, and I can do away with forking altogether. I'm just trying to launch "fire and forget" exe files here.

        system(1, 'this.exe');

        I guess my only other question, then, is "why doesn't ActiveState implement something like this?"...

        --
        Believe nothing, no matter where you read it, or who said it - even if I have said it - unless it agrees with your own reason and your own common sense.
        (Buddha)
Re^2: How to multiprocess in Win32?
by Jenda (Abbot) on Jan 08, 2005 at 19:22 UTC

    This may very well have been true back in 2001, I do remember having problems if I loaded DBI before fork()ing, but I AM running several multithreaded services (daemons for the Unixers) for two or three years already. Works fine. I do not keep creating and destroying threads though, in one service I only have two threads ("watcher" and "worker"), the number of threads in the other depends on the INI file, but again I create them upfront.

    Jenda
    We'd like to help you learn to help yourself
    Look around you, all you see are sympathetic eyes
    Stroll around the grounds until you feel at home
       -- P. Simon in Mrs. Robinson