简体   繁体   中英

How to remove dead children from the array in perl Parallel::ForkManager?

I was advised to use Parallel::ForkManager to demonize. As you can see, I use the run for demonization.

sub run {
    my ($self) = @_;
    my $pfm = Parallel::ForkManager->new($self);
    while(1) {
       $pfm->run_on_wait( sub {
        #some code here
    },sleep(0.0001));
    my $pid = $pfm->start;
        if ($pid != 0) {
            # Parent process
            push @childs, $pid;
            sleep 1;
            next;
        }
        # Child process; do some work
        $self = &doWork();
        # Worker finished, clean up the $pfm instance
        $pfm->finish();

    }
}

All children PIDs are stored in an array @childs , if one of them dies, the cycle allow to restore the desired number of children, but older(dead) PIDs are in the array, how to remove them? And will the new array is visible in the code that located in run_on_wait .

I think you're misusing Parallel::ForkManager .

What it does/is for, is to allow you to automatically limit a number of processes.

You specify the limit when calling the constructor ( new ).

Eg:

my $pfm = Parallel::ForkManager -> new ( $n_concurrent ); 

Usually $self is used to denote object oriented calls.

The run_on_wait method is quite relevant to what you're doing, so it would help if you showed it. But I think you're misunderstanding what it's for, because you're redefining it every iteration of a while loop.

run_on_wait $code, [$period] You can define a subroutine which is called when the child process needs to wait for the startup. If $period is not defined, then one call is done per child. If $period is defined, then $code is called periodically and the module waits for $period seconds between the two calls. Note, $period can be fractional number also. The exact "$period seconds" is not guaranteed, signals can shorten and the process scheduler can make it longer (on busy systems).

But it's really not intended to have an embedded sleep in it. It's supposed to include a wait delay, and it'll run the 'wait' code is called.

But it also doesn't really make sense to redefine this each iteration of your while loop. It's also unclear what you're using @childs for in the first place - why do you need to maintain a list of pids at all - Parallel::ForkManager is tracking numbers and handling joining/waiting for you.

If you need to track your children for some other reason - then you might find it more useful to use the 'start' and 'finish' mechanisms.

start [ $process_identifier ] This method does the fork. It returns the pid of the child process for the parent, and 0 for the child process. If the $processes parameter for the constructor is 0 then, assuming you're in the child process, $pm->start simply returns 0.

An optional $process_identifier can be provided to this method... It is used by the "run_on_finish" callback (see CALLBACKS) for identifying the finished process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM