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

Perl 如何使时间计数器作为与程序并行工作的子进程?,perl,Perl,如何制作一个实时计数器,使其与工作程序的一部分并行地在屏幕上滴答作响 假设我有以下小代码,可以运行一个内部程序几分钟: system (`compile command`); exec "simu -sh"; 在等待它结束时,我可以打开一个fork或输出到stdout运行时钟时间的东西吗 另一个问题可能是,如何在不影响脚本其余部分的情况下输出到屏幕上以显示报警计数器?为您的问题提供上下文非常重要。您已经有两个进程:父进程和子进程。子级将用exec替换自身,因此您不能使用子级执行任何形式的监视

如何制作一个实时计数器,使其与工作程序的一部分并行地在屏幕上滴答作响

假设我有以下小代码,可以运行一个内部程序几分钟:

system (`compile command`);
exec "simu -sh"; 
在等待它结束时,我可以打开一个fork或输出到stdout运行时钟时间的东西吗


另一个问题可能是,如何在不影响脚本其余部分的情况下输出到屏幕上以显示报警计数器?

为您的问题提供上下文非常重要。您已经有两个进程:父进程和子进程。子级将用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;
}

将其生成为线程,然后等待设置一个值(假设您有一个支持线程的perl):

我在WindowsXP上的ActiveState PERL 5.10中运行了上述示例

这将以秒为单位给出完成所需时间的一些指示 执行命令。希望您不会寻找超过一秒钟的粒度。如果需要实际时间,可以用localtime()替换计数器

我没有锁定引用,因为我只关心在例程结束时设置引用,它将完成并加入备份

有关的详细信息


或者看看。

我没有选择,也不知道如何避免使用exec函数。当我运行它时,时间计数器无法停止,可能是因为exec函数在工作场所内运行。当exec命令在时钟计数器内运行时,还有其他方法可以引导时钟计数器吗?或者我可以将报警计数器(属于exec命令kill pid)输出到屏幕上吗?为什么不直接使用system()而不是exec()?我使用了exec(),正如Mani在下面的链接中所建议的那样:如果有其他方法可以使用超时窗口而不会出现死机问题,我很乐意知道:)你正在尝试制作进度条吗?
# 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";