简而言之:使用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/