如何确保一次只运行一个Perl脚本的副本?

pla*_*etp 4 perl locking process flock

我需要确保一次只运行一个Perl脚本的副本.根据这里的建议,我写了一个子进行检查:

sub check_instances {
    open my $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用.可能是什么问题?

cjm*_*cjm 5

你正在使用一个范围内的词法文件句柄.当check_instances返回时,文件句柄将自动关闭,从而释放锁.因此,除非两份副本在同一时间进行检查,否则您永远不会看到冲突.

只要脚本正在运行(或者只要您想保持锁定),请确保文件句柄保持打开状态.例如:

{
my $fh;
sub check_instances {
    return if $fh; # We already checked
    open $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}
} # end scope of $fh
Run Code Online (Sandbox Code Playgroud)

如果您需要Perl 5.10,这也是使用state变量的好地方.