如何在屏幕上创建一个与工作程序的一部分并行的实时计时器?
假设我有以下小子代码运行内部程序几分钟:
system (`compile command`);
exec "simu -sh";
在等待它结束的时候,我可以打开一个叉子或输出到stdout运行时钟时间的东西吗?
另一个问题可能是,如何输出以屏蔽ALARM计数器而不会损害脚本的其余部分?
答案 0 :(得分:3)
为您的问题提供背景信息非常重要。您已经有两个进程:父进程和子进程。孩子正在用exec替换自己,所以你不能使用孩子进行任何形式的监控,但是父母可以使用。我们只需要使waitpid
调用非阻塞(即它不会等待成功,它会立即失败)。这也消除了对eval
和alarm
函数的需求:
#!/usr/bin/perl
use strict;
use warnings;
use POSIX ":sys_wait_h";
my $timeout = 180;
my $program = "simulator --shell";
die "could not fork: $!" unless defined (my $pid = fork);
#this is the child process
unless ($pid) {
exec $program;
#if we reach this code the exec failed
die "exec of simulator failed: $!";
}
#this is the parent process
my $tries = 0;
#check to see if $pid is done, but don't block if it isn't
until (waitpid(-1, WNOHANG) == $pid) {
#put what you want to print while waiting here:
print scalar localtime, "\n";
if ($tries++ > $timeout) {
warn "timed out, sending SIGKILL to simulator\n";
kill 9, $pid;
waitpid($pid, 0);
last;
}
} continue {
sleep 1;
}
答案 1 :(得分:-1)
如何将它作为一个线程生成然后等待设置一个值(假设你有一个启用了线程的perl):
# Modules to be used
use strict;
use warnings;
# Threads module
use Thread;
# Share out the variable so it can be set and
# view by main thread and spawned thread
my $value:shared = 0; # value to be set when completed
# Create a thread with a subroutine to compile and set the passed in reference
# to 1 when complete. Pass in the reference to value
my $t = Thread->new(sub {`compile command`; ${$_[0]} = 1;}, \$value);
# Counter to count
my $count = 0;
# Loop until the routine set the value
while ( $value == 0 )
{
# Increment the count and print it out.
$count++;
print "$count\n";
# Sleep for second to let the other thread process
sleep 1;
}
# Thread as completed so join back together
$t->join();
# Indicate items have completed.
print "Done $count\n";
我在Windows XP上的ActiveState PERL 5.10中运行了上面的示例。
这将在几秒钟内显示出需要多长时间 做命令。希望你不是在寻找超过一秒的粒度。如果您想要实际时间,可以用localtime()代替计数器。
我没有锁定引用,因为我只关心它在设置时(在例程结束时),它将完成并加入备份。
有关perl threads的更多信息。
或者查看Perlmonks。