简体   繁体   English

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

[英]How do I get the PID of a process spawned with Perl's system function?

I'm writing a Perl script (say script.pl ) that calls another script newscript.pl . 我正在写一个调用另一个脚本newscript.pl的Perl脚本(比如script.pl )。 I want to get the PIDs of both the scripts in script.pl only. 我想只在script.pl获取这两个脚本的PID。 I can get the PID of script.pl by using following code 我可以使用以下代码获取script.pl的PID

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

After this I call system to execute newscript.pl 在此之后我调用system来执行newscript.pl

system("perl newscript.pl");

I want to capture the PID generated by this newscript.pl in script.pl . 我想在script.pl捕获这个newscript.pl生成的PID。

The process number of the current process is in $$ . 当前流程的流程编号为$$ Use open3 instead of system to receive the process number of the child process. 使用open3而不是system来接收子进程的进程号。

By the time system returns, the spawned process will have already exited, leaving its pid as an interesting historical reference—useful for log analysis, for example. system返回时,生成的进程已经退出,将其pid留作有趣的历史参考 - 例如,对日志分析很有用。

system LIST
system PROGRAM LIST

Does exactly the same thing as exec LIST , except that a fork is done first and the parent process waits for the child process to exit exec LIST完全相同,除了首先完成fork 并且父进程等待子进程退出 ...

If you want the pids of both script.pl and newscript.pl , fork and manage their lifetimes yourself. 如果你想要script.plnewscript.pl ,请自己fork并管理它们的生命周期。 With more specific information about the problem you're tackling, we could give you more specific suggestions. 有关您正在处理的问题的更具体信息,我们可以为您提供更具体的建议。


To block other instances of a program, a common technique is to use the operating system's facility for cooperative locking: at startup, attempt to lock a certain file. 要阻止程序的其他实例,常见的技术是使用操作系统的工具进行协作锁定:在启动时,尝试锁定某个文件。 If successful, your program knows it's the only one. 如果成功,您的程序就会知道它是唯一的一个。 Otherwise, another process already has the lock, so the new process exits. 否则,另一个进程已经锁定,因此新进程退出。 See below for an example. 请参阅下面的示例。

#! /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.";

Note that you must keep the filehandle returned from take_lock open while control is inside your critical section . 请注意,当控件位于关键部分内时,必须保持take_lock返回的文件句柄take_lock打开状态。 The code above treats it as an opaque token. 上面的代码将其视为不透明的令牌。 When your program exits, Perl closes the filehandle, which releases the lock automatically. 程序退出时,Perl会关闭文件句柄,自动释放锁定。 What you don't want to do is call take_lock in void context because that would discard your lock. 你不想做的是在void上下文中调用take_lock ,因为这会丢弃你的锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM