简而言之:使用flock()编写了一个Perl脚本。在Linux上,它的行为符合预期。在AIX上,即使脚本的另一个实例(使用flock())应在锁定文件上持有排他锁,flock()始终返回1。

我们提供了一个Bash脚本来重新启动我们的程序,它依赖于flock(1)来防止同时重新启动产生多个进程。最近,我们在AIX上进行了部署,其中flock(1)并非默认存在,并且不会由管理员提供。为了使事情简单,我编写了一个名为flock的Perl脚本,如下所示:

#!/usr/bin/perl

use Fcntl ':flock';
use Getopt::Std 'getopts';

getopts("nu:x:");

%switches = (LOCK_EX => $opt_x, LOCK_UN => $opt_u, LOCK_NB => $opt_n);

my $lockFlags = 0;

foreach $key (keys %switches) {
    if($switches{$key}) {$lockFlags |= eval($key)};
}

$fileDesc = $opt_x || $opt_u;

open(my $lockFile, ">&=$fileDesc") ||  die "Can't open file descriptor: $!";
flock($lockFile, $lockFlags) || die "Can't change lock - $!\n";;

我通过从两个终端选项卡几乎同时运行两次(flock -n -x 200; sleep 60)200> lockfile来测试了脚本。

在Linux上,第二次运行按预期终止,显示“资源暂时不可用”。

在AIX上,第二次运行将获取该锁,而flock()返回1,这是绝对不希望的。

我了解flock()在两个系统上的实现方式有所不同,Linux版本使用flock(1),而AIX使用fcntl(1)。我没有足够的专业知识,以了解这如何导致我的问题以及如何解决它。

非常感谢您的任何建议。

最佳答案

这与AIX无关,脚本中的open()调用不正确。

应该是这样的:

open (my $lockfile, ">>", $fileDesc) # for LOCK_EX, must be write

您在>&=中使用了“dup()先前打开的文件句柄”语法,但是脚本没有打开任何要复制的文件,也不应该打开。

我的快速测试显示了正确的行为(已添加调试)
first window:
$ ./flock.pl -n -x lockfile
opened lockfile
locked
second window:
$./flock.pl -n -x lockfile
opened lockfile
Can't change lock - Resource temporarily unavailable
$

关于perl - Perl:flock()在Linux上有效,忽略先前在AIX上的锁定,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10347683/

10-10 22:40