in reply to Re^2: Parallel::ForkManager and wait_all_children
in thread Parallel::ForkManager and wait_all_children
If you exec another program, the running perl is terminated so can't send the alarm.
alarm causes the system to send SIGALRM to the current process.
Don't you have to use system() and kill the child process if it times out?
You can't kill a child if you're waiting for it to exit using system, so you'd have to replace system.
use IPC::Open3 qw( open3 ); use POSIX qw( WNOHANG ); use constant TIMEOUT => 60; sub wait_for_test_to_end { my ($pid) = @_; my $abs_timeout = time() + TIMEOUT; while (1) { return if waitpid($pid, WNOHANG) > 0; last if time() > $abs_timeout; sleep(1); } kill(ALRM => $pid); $abs_timeout = time() + 15; while (1) { return if waitpid($pid, WNOHANG) > 0; last if time() > $abs_timeout; sleep(1); } kill(KILL => $pid); waitpid($pid, 0); } while (1) { for my $runCommand (@runArray) { $forkMgr->start($runCommand) and next; my $pid = open3('<&STDIN', '>&STDOUT', '>&STDERR', "/usr/localcw/opt/patrol/nagios/libexec/$runCommand"); wait_for_test_to_end($pid); $forkMgr->finish($? & 0x7F ? 0x80 | ($? & 0x7F) : $? >> 8); } $forkMgr->wait_all_children; sleep 10; }
And you're back to having a useless process between the manager than the test.
On the plus side, you can use more complex conditions than a simple timeout. You can also forcibly kill the process if it doesn't respond to SIGALRM as the above demonstrates.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Parallel::ForkManager and wait_all_children
by rgren925 (Beadle) on May 13, 2015 at 22:13 UTC | |
by ikegami (Patriarch) on May 14, 2015 at 14:31 UTC |