Как сделать счетчик времени дочерним процессом, который работает параллельно программе? - PullRequest
2 голосов
/ 03 августа 2009

Как сделать счетчик времени в реальном времени, который будет отображаться на экране параллельно части рабочей программы?

допустим, у меня есть следующий небольшой субкод, который запускает внутреннюю программу в течение пары минут:

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

В ожидании завершения, могу ли я открыть разветвление или что-то, что выводит на стандартный таймер?

Еще один вопрос: как я могу вывести на экран счетчик ALARM, не повредив остальной части сценария?

Ответы [ 2 ]

3 голосов
/ 03 августа 2009

Важно дать контекст вашему вопросу. У вас уже есть два процесса: родитель и ребенок. Дочерний объект заменяет себя на 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;
}
0 голосов
/ 04 августа 2009

Как насчет порождения его как потока и последующего ожидания установки значения (при условии, что у вас включен поток 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";

Я запустил приведенный выше пример в ActiveState PERL 5.10 для Windows XP.

Это даст некоторое представление в секундах о том, сколько времени ушло на выполнить команду. Надеюсь, вы не ищете более секунды детализации. Вы можете заменить localtime () на счетчик, если хотите указать фактическое время.

Я не блокирую ссылку, так как меня беспокоит только то, что она установлена, то есть в конце процедуры, чтобы она завершилась и снова включилась.

Для получения дополнительной информации о потоках Perl .

Или посмотрите на Perlmonks .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...