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

So a program that uses ActiveState's fork() is giving stray pointer crashes when run, sometimes?

Any machine-level stray pointer in a pure Perl (no XS, no API calls) program is by definition a Perl bug.

In a compiled language, a debugger easily spots the instruction doing that and lets you view the stack to see what it was up to. I don't know how you'd do it in Perl. A general-purpose mechanism would be to "confess" the stack trace any time a machine-level exception or signal is encountered. I have no idea how to set things up to do that, but I think it ought to be built-in.

—John

  • Comment on Re: Re: Re: How to multiprocess in Win32?

Replies are listed 'Best First'.
(tye)Re: How to multiprocess in Win32?
by tye (Sage) on Aug 31, 2001 at 23:30 UTC

    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")
      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        

      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