如何获得使用Perl系统函数生成的进程的PID?

时间:2012-02-22 11:37:29

标签: perl system pid

我正在编写一个调用另一个脚本script.pl的Perl脚本(比如newscript.pl)。我想只在script.pl中获取两个脚本的PID。我可以使用以下代码

获得script.pl的PID
my $pid = Unix::PID->new();
my @p = $pid->get_pidof( $pid->get_command($$), 1 );

在此之后,我致电system执行newscript.pl

system("perl newscript.pl");

我想捕获newscript.plscript.pl生成的PID。

2 个答案:

答案 0 :(得分:9)

当前流程的流程编号位于$$。使用open3代替system来接收子进程的进程号。

答案 1 :(得分:5)

system返回时,生成的进程已经退出,将其pid留作有趣的历史参考 - 例如,对日志分析很有用。

  

<强> system LIST
  的 system PROGRAM LIST

     

exec LIST完全相同,除了fork首先完成并且父进程等待子进程退出 ...

如果你想要script.plnewscript.plfork的pid并自己管理他们的生命。有关您正在处理的问题的更具体信息,我们可以为您提供更具体的建议。


要阻止程序的其他实例,常见的技术是使用操作系统的工具进行协作锁定:在启动时,尝试锁定某个文件。如果成功,您的程序就会知道它是唯一的一个。否则,另一个进程已经锁定,因此新进程退出。请参阅下面的示例。

#! /usr/bin/env perl

use strict;
use warnings;

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

$0 = basename $0;

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

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

sub take_lock {
  open my $fh, ">", $LOCK or die "$0: 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返回的文件句柄,同时控件位于critical section内。上面的代码将其视为不透明的令牌。程序退出时,Perl会关闭文件句柄,自动释放锁定。你不想做的是在void上下文中调用take_lock因为这会丢弃你的锁。