【问题标题】:What's the best way to make sure only one instance of a Perl program is running?确保只有一个 Perl 程序实例在运行的最佳方法是什么?
【发布时间】:2010-10-02 03:19:14
【问题描述】:

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

这是我能想到的:

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

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

【问题讨论】:

标签: perl process mutual-exclusion


【解决方案1】:

使用旧的 PID 文件技巧。

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

HTH

干杯,

罗伯

【讨论】:

  • 这可以通过从文件中读取 PID 并检查进程是否仍然存在(使用 kill 0, $pid)来改进。如果没有,则忽略旧的 pid 文件并继续。这有助于从崩溃的进程中更优雅地恢复。
  • +1 用于检查文件中找到的 pid 是否存在,用信号 0 杀死只是为了那个。
  • 请注意,如果两个进程尝试同时启动,同时检查文件,并且两个进程都没有创建 pid 文件,这也会产生竞争条件。
  • 如果 myprog.pl 崩溃,此方法不起作用。 PID 编号会在一段时间后重新使用,因此即使该进程现在存在,它也可能是一些不同的程序或守护进程正在运行。如果 myprog.pl 以某种方式保证在一分钟内结束,并且 myprog.$$ 文件比这更旧,那么您可以假设它是另一个进程并继续进行。 ($$ 当然是你运行的 myprog.pl 的 PID 号)。要检查它是否是另一个进程,您可以在 Linux(至少某些 Linux 系统)上解析 qx(ps aux|grep $$)/proc/$$/cmdline。我会选择上面的flock 方法。
【解决方案2】:

有很多方法可以做到这一点。 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";

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

【讨论】:

  • 似乎不能很好地与 ActiveState Perl 一起使用...其他人尝试过吗?
  • @MikeKulls perlop 中的precedence table 可能会有所帮助。知道or 是该语言中优先级最低的运算符,这很有帮助。
  • @MikeKulls:抱歉,这是风格/个人偏好的问题。如果您真的想要尝试 lisp,IMO 优先级不是您想要“避免尝试知道”的东西。对我来说,添加多余的括号只会增加心理解析的工作量。
  • 顺便说一句,关于“避免试图知道”,当我开始编程时,我曾经学习过我正在使用的语言的每一个微小细节。我会编写使用这些小怪癖的代码来保存一些字符。这些天来,我不能被打扰,而是编写代码,所以如果语言的那些特性以一种或另一种方式出现,那么我的代码仍然可以工作。 Perl 比我用过的任何其他语言都有更多的特性和快捷方式,我发现如果你不是 Perl 专家,那么使用所有这些编写的代码是很难理解的。
  • «我的意思是当你有 |和“或”在一行中,一些括号是有意义的»。在每种 C 派生语言(和其他语言)中,二进制或比逻辑或具有更严格的优先级;这不是 Perl 的特质。 «$0 or» 是 Perl 的特性,但您必须意识到使用低优先级逻辑运算符(除了高优先级 || 和 &&)的全部意义在于可以避免使用括号。
【解决方案3】:

您列出的所有选项都很好。不过,有一件事是要注意,在极少数情况下,您最终可能会得到一个运行很长时间的进程(即,等待某事)。您可能需要考虑关注其他正在运行的实例已经运行了多长时间,如果超过一定时间(例如一天),可能会向自己发送警报。

【讨论】:

    猜你喜欢
    • 2010-12-15
    • 2010-09-27
    • 1970-01-01
    • 2023-03-27
    • 2017-10-01
    • 2011-07-20
    相关资源
    最近更新 更多