简而言之:使用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)。我没有足够的专业知识来理解这是如何导致我的问题,以及如何解决它。
非常感谢您的任何建议。
答案 0 :(得分:2)
我想,这不是关于不同的命令;它更多地是关于AIX和Linux之间的全局差异。
在POSIX系统中,文件锁是建议性的:每个程序都可以检查文件的状态,然后重新考虑要用它做什么。没有明确的检查=没有锁定。
然而,在Linux系统中,人们可以尝试强制执行强制锁定,尽管文档本身声明依赖它是不明智的:实现是(并且可能永远都是)错误。
因此,我建议在脚本本身内实现顾问标志的检查。
有关它的更多信息:man 2 fcntl,man 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
$