当我执行以下操作时,我没有看到任何锁定文件(如果flock()使用该文件?)。
问题是我可以多次运行相同的脚本,并且它不会提交文件。
我是否需要安装Fnctl
套餐?
我做错了什么?
#!/usr/bin/perl
use warnings;
use strict;
use Fcntl ':flock'; # Import LOCK_* constants
my $file = 't';
my $can_lockin = 1;
open(my $fh, '>', $file) or die "Could not open '$file' - $!";
flock($fh, LOCK_EX) or die "Could not lock '$file' - $!";
print $fh $can_lockin;
sleep 100000000;
#close($fh) or die "Could not write '$file' - $!";
答案 0 :(得分:4)
flock
不使用锁定文件;它由操作系统实现。
请记住,UNIX锁是顾问,即其他程序仍然可以修改该文件,除非他们自己调用flock
。此外,如果文件被锁定,flock
尝试阻止(等待文件解锁)。如果您希望程序在尝试获取保持锁定时退出而不是阻止,请将LOCK_EX | LOCK_NB
传递给flock
。
另请注意,您的打开模式是错误的,而不是>
(截断文件),您可能需要<+
(打开文件进行读写)并自己致电truncate
获得锁定后。
答案 1 :(得分:2)
我想你想要这样的东西:
#!/usr/bin/perl
use strict;
use Fcntl ':flock';
$|++; # no buffering
my $file = "status.txt";
open my $fh, '+<', $file or die "can't open $file in update mode: $!\n";
flock($fh, LOCK_EX) or die "couldn't get lock: $!\n";
my $status = <$fh>;
chomp $status;
$status = $status ? '0' : '1';
seek $fh, 0, 0;
print $fh "$status\n";
truncate($fh, tell($fh));
#print "blocking...\n"; sleep 10;
close $fh;
这将在1和0之间来回切换status.txt文件的内容。 请注意,我在“更新模式”下打开文件,因为我需要读取和写入。如果你 不要这样做你可以获得竞争条件。如果取消注释“睡眠”行, 开始在一个窗口中运行,然后在另一个窗口中再次运行它,你会看到 第二次运行等待flock直到第一次运行关闭文件(释放锁定)。
答案 2 :(得分:1)
如果你添加一些调试输出,你会发现flock()是阻塞的,你的脚本几乎正常工作:
...
print "Pre lock\n";
flock($fh, LOCK_EX) or die "Could not lock '$file' - $!";
print "Post lock\n";
...
您可以通过LOCK_NB按位或按LOCK_EX来解决这个问题。