3

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

我们发布了一个 Bash 脚本来重新启动我们的程序,依靠 flock(1) 来防止同时重新启动产生多个进程。最近我们部署在 AIX 上,默认情况下,flock(1) 不会出现,管理员也不会提供。为了简单起见,我写了一个 Perl 脚本,叫做flock,像这样:

#!/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)。我没有足够的专业知识来了解这如何导致我的问题以及如何解决它。

非常感谢您的任何建议。

4

2 回答 2

2

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

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

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

因此,我建议在脚本本身内实现对咨询标志的此类检查。

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

于 2012-04-27T09:40:15.360 回答
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
$
于 2012-04-27T22:24:47.590 回答