Perl:flock()适用于Linux,忽略了以前对AIX的锁定

时间:2012-04-27 08:54:36

标签: perl aix file-locking flock

简而言之:使用flock()编写了一个Perl脚本。在Linux上,它的行为与预期一致。在AIX上,flock()总是返回1,即使使用flock()的另一个脚本实例应该在lockfile上持有一个独占锁。

我们发布了一个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)。我没有足够的专业知识来理解这是如何导致我的问题,以及如何解决它。

非常感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

我想,这不是关于不同的命令;它更多地是关于AIX和Linux之间的全局差异。

在POSIX系统中,文件锁是建议性的:每个程序都可以检查文件的状态,然后重新考虑要用它做什么。没有明确的检查=没有锁定。

然而,在Linux系统中,人们可以尝试强制执行强制锁定,尽管文档本身声明依赖它是不明智的:实现是(并且可能永远都是)错误。

因此,我建议在脚本本身内实现顾问标志的检查。

有关它的更多信息:man 2 fcntlman 2 flock

答案 1 :(得分: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
$