Инициирование не ожидающего фонового процесса в Perl - PullRequest
2 голосов
/ 13 декабря 2010

У меня есть сценарий Perl, который должен запустить другой процесс в фоновом режиме и завершить работу, не дожидаясь завершения другого сценария.В StackOverflow существует множество потоков, в которых рассказывается, как ждать в Perl или как не ждать других языков программирования, но я не могу найти правильный ответ для Perl.

Я прочитал довольноЯ подумал, что делаю правильные вещи, но ни одна из моих попыток, похоже, не работает правильно.Вот все варианты, которые я пробовал до сих пор безрезультатно:

system(qq|perl /util/script.pl $id|);

system(qq|perl /util/script.pl $id &|);

exec(qq|perl /util/script.pl $id|);

exec(qq|perl /util/script.pl $id &|);

С каждым из них родительский процесс продолжает ждать, пока ребенок завершит работу, прежде чем выйти.Пожалуйста, дайте мне знать, что я делаю неправильно, и правильный способ раскошелиться на фоновый процесс.

Заранее спасибо за вашу помощь!


Полный код, помогающий с отладкой.Обратите внимание, что вызовы API-> Function () являются объектно-ориентированными модулями, которые наша кодовая база использует для конкретных функций, взаимодействующих с базой данных, и т. Д .:

sub Add {
    my $self = shift;
    my $domain = shift;

    if(!$self->IsValid($domain)) { return; }

    my $SQL = qq| insert into domains set added=NOW(),domain=| . API->Database->Quote($domain);
    my $sth = API->DatabaseQuery($SQL);

    $SQL = qq| select last_insert_id() |;
    $sth = API->DatabaseQuery($SQL);
    my $id = $sth->fetchrow_array();

    my $command = qq|perl /home/siteuser/util/new.pl $id &|;
    system($command);

    return {'id'=>$id,'domain'=>$domain};
}

Ответы [ 4 ]

4 голосов
/ 13 декабря 2010

Первый из них предназначен для такой работы - system выполняет команду и завершает ее до конца.

Последние два также разработаны таким образом - exec специально разработан, чтобы никогда не возвращаться. В основном он заменяет родительский процесс дочерним процессом.

Однако, второй должен сделать свое дело: команда, запущенная из вызова system, является оболочкой, которой дается ваша строка для выполнения. Поскольку строка заканчивается символом «&», это означает, что оболочка запустит вашу команду как фоновый процесс и завершит свое собственное выполнение после этого запуска.

Не могли бы вы опубликовать больше кода, иллюстрирующего, как # 2 не работал?

Кроме того, посмотрите, что произойдет, если вы попробуете обратные пометки или qx:

my $output = qx|perl /util/script.pl $id &|;
print $output;

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

my $output = qx|(echo "AAAAAAA"; /bin/date; sleep 5; /bin/date; echo "BBBBBBB") &|;
print $output;
3 голосов
/ 13 декабря 2010

Вам необходимо отсоединить ребенка от родителя.Смотрите perldoc -q daemon.Или Proc :: Daemon

3 голосов
/ 13 декабря 2010

Вы звоните fork(), прежде чем позвонить system или exec?

my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    my $exit_code = system( $command );
    exit $exit_code >> 8;
}


my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    exec( $command );
    # doesn't^H^H^H^H^H^H shouldn't return
}
0 голосов
/ 13 декабря 2010

Использование fork - хороший способ фоновых процессов:

my $pid = fork;
die "fork failed" unless defined $pid;
if ($pid == 0) {
    # child process goes here
    do '/util/script.pl';
    exit;
}
# parent process continues here
...