Perl 中的 Flock 不起作用

Flock in Perl doesnt work

我有一个 Perl 文件。用户打开一个文件,读取数据并在网格中显示数据。用户对其进行编辑并将其保存回文件。

我正在尝试使用 flock,这样当用户读取文件时,文件就会被锁定。我试过下面的代码,但没有用。

参考这个post的已接受答案。 How do I lock a file in Perl?

use Fcntl ':flock';                         #added this at the start
$filename= dsfs.com/folder1/test.txt;        #location of my file

open(my $fh, '<', $filename) or die $!;     #file open
flock($fh, LOCK_EX) or die "Could not lock '$file' - $!"; #inserted flock before reading starts so that no other user can use this file
#reading of file starts here
#once read, user saves file. 

close($fh) or die "Could not write '$file' - $!"; #release lock after user writes. 

我想这是一个正常的操作,没有任何条件竞争,但这不适用于 me.I 我不确定 perl 脚本是否能够检测到 flock。

出于测试目的,我尝试在写入和保存功能完成之前打开文件。当我尝试在保存完成之前打开同一个文件时,这意味着锁定尚未释放。在这种情况下,如果我在后端打开文件并编辑文件,我仍然能够保存更改。在实际情况下,一旦文件被锁定,它就不能编辑任何东西。

任何人都可以建议我解决这个问题,或者我使用 flock 的过程不正确吗??

有两个问题:

  • flock 将阻塞直到它可以锁定。因此你需要 flock ( $file, LOCK_EX | LOCK_NB ) or die $!;
  • flock(在 Unix 上)是建议性的。它不会阻止他们访问它,除非他们也检查锁。

如果您的 flock 实现是基于 lockf(3)fcntl(2),则可能存在另一个问题。即,LOCK_EX 应与 "write intent" 一起用于为输出打开的文件。

对于lockf(3)perldoc -f flock表示

Note that the emulation built with lockf(3) doesn't provide shared locks, and it requires that FILEHANDLE be open with write intent.

fcntl(2):

Note that the fcntl(2) emulation of flock(3) requires that FILEHANDLE be open with read intent to use LOCK_SH and requires that it be open with write intent to use LOCK_EX.

输入文件或更复杂的同步操作的解决方法是让所有进程在一个普通的锁定文件上同步,例如:

open my $lock, '>>', "$filename.lock";
flock $lock, LOCK_EX;

# can't get here until our process has the lock ...
open(my $fh, '<', $filename) or die $!;     #file open
... read file, manipulate ...
close $fh;
open my $fh2, '>', $filename;
... rewrite file ...
close $fh2;

# done with this operation, can release the lock and let another
# process access the file
close $lock;