in reply to making fork() a flag, and wait()ing properly

Wouldn't having a wait() inside the loop make the code execute as if it wasn't forking? consider this simplified version of your script:

## simplified code, so no error checking... foreach my $node (@devices) { my $pid = fork(); if( !$pid ) { ## child... exit 0; } ## parent wait(); }

So this means that for each node, you fork off a process, and immediately afterwards the parent waits for that process. The parent will block until the child is done. Thus no merit of forking here...

You need to do something like this:

use POSIX; $SIG{CHLD} = sub { while( ( my $pid = waitpid(-1, POSIX::WNOHANG()) ) > 0 ){ ## cleanup code... ## you probably should save the forked ## pids and make sure that the result of ## waitpid is indeed your child } } foreach my $nod ( @devices ) { my $pid = fork(); if( !$pid ) { ## child... } }

Now, as for your switching needs, I might do something like this:

use POSIX; my $do_fork = 1; $SIG{CHLD} = sub { while( ( my $pid = waitpid(-1, POSIX::WNOHANG()) ) > 0 ){ ... } } foreach my $node ( @devices ) { if( $do_fork ) { my $pid = fork(); if( !$pid ) { do_exciting_things(); exit 0; } } else { do_exciting_things(); } }

This is obviously just a psuedocode, so make sure to put plenty more error checking and all that stuff.

Replies are listed 'Best First'.
Re: Re: making fork() a flag, and wait()ing properly
by c (Hermit) on Feb 08, 2002 at 19:09 UTC
    Nice! Your last example of:

    foreach my $node ( @devices ) { if( $do_fork ) { my $pid = fork(); if( !$pid ) { do_exciting_things(); exit 0; } } else { do_exciting_things(); } }

    looks very much like my most recent rewrite after starting this thread, so i am very encouraged that I am actually starting to understand what it is you dudes actually are talking about :-)

    maybe though you could clear up the fog for me on this:

    use POSIX; my $do_fork = 1; $SIG{CHLD} = sub { while( ( my $pid = waitpid(-1, POSIX::WNOHANG()) ) > 0 ){ ... } }

    this one has me scratching my head. if you'd rather point to a perldoc reference, i'm up for that as well. it looks as though you're defining a subroutine as a hash value, but i'm not certain where/how its being called.

    thanks -c

      Are you asking me about just the syntax? or about signal handling with %SIG ?

      As far as the syntax goes, my code is equivalent to something like this:

      my $coderef = sub{ .... }; ## now $coderef is a reference to a subroutine, ## which can be executed like this: ## ## $coderef->(); # $coderef->( @args ) ## $SIG{ CHLD }= $coderef;

      So that means you can actually create an anonymous subroutine, and assign it to a scalar. Which in turn can be assigned to a hash value :)

      As for the signal handling portion, perldoc perlipc will give you more information. Not sure what is the best resource for that... ( I could try to explain, but I'm not confident that my knowledge is 100% correct )