我想等待两个进程(或更多)完成,或者计时器倒计时。定时器倒计时将在终端窗口中输出。例如:
use warnings;
use strict;
use feature qw(say);
my $pid1 = fork();
if ( $pid1 == 0 ) {
runTask1();
exit 0;
}
my $pid2 = fork();
if ( $pid2 == 0 ) {
runTask2();
exit 0;
}
my $timer = startTimer();
say "Waiting for child processes..";
my $counter = 20;
my $i = 0;
while (1) {
my $pid = wait;
last if ( $pid == -1 );
if ( $pid == $timer ) {
$counter--;
say $counter;
$timer = startTimer();
} else {
say "Child with PID=$pid finished..";
$i++;
last if $i == 2;
}
}
say "Done.";
sub startTimer {
my $pidTimer = fork();
if ( $pidTimer == 0 ) {
sleep 1;
exit 0;
}
return $pidTimer;
}
sub runTask1 {
sleep 10;
exit 0;
}
sub runTask2 {
sleep 5;
exit 0;
}
我对这种方法的关注是我为计时器创建了一个分叉的子进程,这似乎有些过分。这是必要的,还是有更简单的方法?
答案 0 :(得分:4)
查看alarm()
- 在指定的超时后触发一个终止信号ALRM
。哪个会破坏流程,或者你可以使用:
$SIG{'ALRM'} = \&some_sub_to_handle_alarms;
alarm()
不会传播到分叉流程,因此您可以在父母的“父母”上进行设置。所以它只是等待孩子的时间。
你可能不需要分叉你的pidTimer - 你可以让你的主进程坐在循环中。
以下演示:
use strict;
use warnings;
use feature qw(say);
my $pid1 = fork();
if ( $pid1 == 0 ) { # Simulated Task 1
sleep 10;
exit 0;
}
my $pid2 = fork();
if ( $pid2 == 0 ) { # Simulated Task 2
sleep 5;
exit 0;
}
say "Waiting for child processes..";
my $counter = 20;
local $SIG{ALRM} = sub {
say --$counter;
alarm 1;
};
alarm 1;
while ((my $pid = wait) != -1) {
say "Child with PID=$pid finished..";
}
alarm 0;
say "Done.";
输出:
Waiting for child processes..
19
18
17
16
Child with PID=55240 finished..
15
14
13
12
11
Child with PID=55239 finished..
Done.