确保只有一个Perl程序实例正在运行的最佳方法是什么?

Tom*_*ner 24 perl process mutual-exclusion

有几种方法可以做到这一点,但我不确定哪一种是最好的.

这是我能想到的:

  • 使用pgrep查找进程.
  • 让脚本使用flock锁定自己,然后在每次运行时检查它是否被锁定.
  • 在/var/run/program_name.pid中创建一个pid文件并检查是否存在,并在需要时比较pid.

可能有更多方法可以做到这一点.您认为最好的方法是什么?

Leo*_*ans 39

有很多方法可以做到这一点.PID文件是传统的方法.您也可以对文件进行锁定,例如程序本身.这段小代码可以解决这个问题:

use Fcntl ':flock';
open my $self, '<', $0 or die "Couldn't open self: $!";
flock $self, LOCK_EX | LOCK_NB or die "This script is already running";
Run Code Online (Sandbox Code Playgroud)

与PID文件相比的一个优点是文件在程序退出时自动解锁.以可靠的方式实施起来要容易得多.

  • @MikeKulls perlop 中的 [优先级表](http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity) 可能会有所帮助。知道 `or` 是该语言中最低优先级的运算符会很有帮助。 (2认同)
  • @MikeKulls:对不起,但这是关于风格/个人偏好的问题.IMO优先级不是你想"避免试图知道"的东西,如果你真的想要尝试lisp.对我来说,添加多余的括号只会增加心理解析的效果. (2认同)
  • «我的意思是当你有 | 和“或”在一行中的一些括号有意义»。在每种 C 派生语言(和其他语言)中,二进制或比逻辑或具有更严格的优先级;这不是 Perl 的特性。«$0 or» 是 Perl 的特性,但您必须意识到使用低优先级逻辑运算符(除了高优先级 || 和 &amp;&amp;)的全部意义在于您可以避免使用括号。 (2认同)

Rob*_*lls 10

做旧的PID文件技巧.

  • 开始过程
  • 看看是否有一个名为"myprog.PID"的文件
  • 检查是否存在正在运行的proc.使用kill 0,$ pid匹配PID
  • 如果编程PID proc的名称.比赛,大声抱怨并退出
  • 如果没有,清理陈旧的"myprog.PID"
  • 创建一个名为"myprog.PID"的文件,然后继续

HTH

干杯,

  • 这可以通过从文件中读取PID并检查进程是否仍然存在(使用kill 0,$ pid)来改进.如果没有,则忽略旧的pid文件并继续.这有助于从崩溃的进程中更优雅地恢复. (6认同)
  • 请注意,如果两个进程同时尝试启动,同时检查文件,并且都没有提交pid文件,则这也会出现争用情况. (3认同)