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

I'm trying to compile the simplest snippet I can using pp with Strawberry Perl on Windows tp submit threads.

The code runs just fine with just loose perl

Running "pp -x ThreadTest.pl -o ThreadTest.o" runs just fine and creates an exe file.

Running the resulting executable fails every time.

Parent reports child. Child reports in and runs, then fails as last child code exits.

If run with multiple threads, all submit, all check in, all seem to exit, then it errors out.

How can we compile code with threads for windows? Is it a perl problem or a Windows problem?

#Hash of Child PIDs our %ChildPids; #my $MaxThreadsAtOneTime = 5; #my $MaxThreadsAtOneTime = 2; my $MaxThreadsAtOneTime = 1; my $ThreadsToRun = 50; #### MAIN # Submit first group of children print("Submitting first batch of children\n"); my $ThreadNum = 0; while (($ThreadNum < $MaxThreadsAtOneTime) && ($ThreadNum < $ThreadsToRun)) { $ThreadNum++; my $ChildPid; if ($ChildPid = fork) { # parent code # Collect pid print("Parent found Child $ThreadNum with pid $ChildPid\n"); $ChildPids{$ChildPid} = $ThreadNum; } elsif (defined $ChildPid) { # child code print(" Child pid $$ checking in as thread $ThreadNum\n"); my $SleepTime = int(rand(30)); print(" Child pid $$ sleeping for $SleepTime seconds\n"); sleep $SleepTime; print(" Child pid $$ exiting\n"); exit(); } }
  • Comment on Compiling with pp on Strawberry Perl on Windows with threads fails
  • Download Code

Replies are listed 'Best First'.
Re: Compiling with pp on Strawberry Perl on Windows with threads fails
by NetWallah (Canon) on Jul 07, 2016 at 21:36 UTC
    Your child process management logic is flawed.

    Try this (slightly improved, but simplistic) code:

    use strict; use warnings; #Hash of Child PIDs our %ChildPids; #my $MaxThreadsAtOneTime = 5; my $MaxThreadsAtOneTime = 2; #my $MaxThreadsAtOneTime = 1; my $ThreadsToRun = 10; #### MAIN # Submit first group of children print("Submitting first batch of children\n"); my $ThreadNum = 0; my $activeThreads = 0; while ($ThreadNum < $ThreadsToRun) { $ThreadNum++; my $ChildPid; if ($activeThreads >= $MaxThreadsAtOneTime){ print "Waiting for a thread to finish\n"; for (keys %ChildPids){ my $rslt = waitpid( $_,0 ); print "Waiting pid $_ = ", $rslt , "\n"; delete $ChildPids{$_}; # So we dont wait again.. last; } $activeThreads --; } if ($ChildPid = fork) { # parent code # Collect pid print("Parent Created Child $ThreadNum with pid $ChildPid\n"); $ChildPids{$ChildPid} = $ThreadNum; $activeThreads++; } elsif (defined $ChildPid) { # child code print(" Child pid $$ checking in as thread $ThreadNum\n"); my $SleepTime = int(rand(10)); print(" Child pid $$ sleeping for $SleepTime seconds\n"); sleep $SleepTime; print(" Child pid $$ exiting\n"); exit(); } } print "Parent Code done after ThreadNum=$ThreadNum .. Waiting\n"; for (keys %ChildPids){ print "Waiting pid $_ = ", waitpid( $_,0 ) , "\n"; } print "Exiting Parent\n";

            There is no time like the present for postponing what you ought to be doing.

      I tried your version, and it does work running just the perl on Windows 7 with Strawberry Perl

      This is perl 5, version 24, subversion 0 (v5.24.0) built for MSWin32-x64-multi-thread

      Running with pp also works to create the exe file

      pp -x ThreadTest2.pl -o ThreadTest2.exe

      But when running the created executable, it gets the same popup error as my version.

      ThreadTest2.exe has stopped working

      I've been told by other co-workers that this "behavior" is also seen with pp on ActiveState perl and with Perl2Exe compiler, though I haven't tested those. Still scratching my head.

        This sample code shows the author using a "select" to "sleep", after invoking "fork". Other Internet postings also indicate the need for sleep after fork, on Windows.

        Could you try adding a "sleep 1;" after the fork, to see if that helps ? (I am having trouble installing a working PAR::Packer).

                There is no time like the present for postponing what you ought to be doing.