Как получить PID процесса, порожденного системной функцией Perl?

я пишу сценарий Perl (скажем script.pl), который вызывает другой скрипт newscript.pl. Я хочу получить PIDs обоих сценариев в script.pl только. Я могу получить PID script.pl использовать следующий код

my $pid = Unix::PID->new();
my @p = $pid->get_pidof( $pid->get_command($$), 1 );

после этого я называю system для выполнения newscript.pl

system("perl newscript.pl");

Я хочу захватить PID, созданный этим newscript.pl на script.pl.

2 ответов


времени system возвращает, порожденный процесс уже вышел, оставив свой pid в качестве интересной исторической ссылки-полезной для анализа журнала, например.

system LIST
system PROGRAM LIST

делает то же самое, что и exec LIST, за исключением того, что a fork делается первая и родительский процесс ждет завершения дочернего процесса ...

если вы хотите pids обоих script.pl и newscript.pl, fork и управлять своими жизнями самостоятельно. С более конкретной информацией о проблеме, которую вы решаете, мы могли бы дать вам более конкретные предложения.


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

#! /usr/bin/env perl

use strict;
use warnings;

use Fcntl qw/ :flock /;
use File::Basename;
use POSIX qw/ strftime /;

 = basename ;

my $LOCK = "$ENV{HOME}/.lock-";

sub logmsg {
  my($msg) = @_;
  my $t = strftime "%F %T", localtime time;
  warn ": $t - $$ - $msg\n";
}

sub take_lock {
  open my $fh, ">", $LOCK or die ": open $LOCK: $!";

  unless (flock $fh, LOCK_EX | LOCK_NB) {
    logmsg "failed to lock $LOCK; exiting.";
    exit 1;
  }

  $fh;
}

my $token = take_lock;
logmsg "processing...";
sleep 2 * 60;
logmsg "done.";

обратите внимание, что вы должны сохранить файловую ручку, возвращенную из take_lock открыть, а контроль внутри критическая секция. Приведенный выше код рассматривает его как непрозрачный токен. Когда ваша программа завершает работу, Perl закрывает файловую ручку, которая автоматически освобождает блокировку. То, что вы не хотите делать, это call take_lock в пустом контексте, потому что это будет отменить блокировку.


номер процесса текущего процесса находится в $$. Использовать open3 вместо system для получения номера процесса дочернего процесса.