如何将时间计数器作为与程序并行工作的子进程?

时间:2009-08-03 12:52:05

标签: perl

如何在屏幕上创建一个与工作程序的一部分并行的实时计时器?

假设我有以下小子代码运行内部程序几分钟:

system (`compile command`);
exec "simu -sh"; 

在等待它结束的时候,我可以打开一个叉子或输出到stdout运行时钟时间的东西吗?

另一个问题可能是,如何输出以屏蔽ALARM计数器而不会损害脚本的其余部分?

2 个答案:

答案 0 :(得分:3)

为您的问题提供背景信息非常重要。您已经有两个进程:父进程和子进程。孩子正在用exec替换自己,所以你不能使用孩子进行任何形式的监控,但是父母可以使用。我们只需要使waitpid调用非阻塞(即它不会等待成功,它会立即失败)。这也消除了对evalalarm函数的需求:

#!/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