gpt4 book ai didi

linux - 为什么 File::FcntlLock 的 l_type 总是 "F_UNLCK"即使文件被锁定?

转载 作者:IT王子 更新时间:2023-10-29 01:07:35 31 4
gpt4 key购买 nike

下面的 Perl 子例程使用 File::FcntlLock 来检查文件是否被锁定。

为什么它返回0并打印/tmp/test.pid is unlocked. 即使文件被锁定?

sub getPidOwningLock {
my $filename = shift;

my $fs = new File::FcntlLock;
$fs->l_type( F_WRLCK );
$fs->l_whence( SEEK_SET );
$fs->l_start( 0 );
$fs->l_len( 0 );

my $fd;
if (!open($fd, '+<', $filename)) {
print "Could not open $filename\n";
return -1;
}

if (!$fs->lock($fd, F_GETLK)) {
print "Could not get lock information on $filename, error: $fs->error\n";
close($fd);
return -1;
}

close($fd);

if ($fs->l_type() == F_UNLCK) {
print "$filename is unlocked.\n";
return 0;
}

return $fs->l_pid();
}

文件被锁定如下(lock.sh):

#!/bin/sh
(
flock -n 200
while true; do sleep 1; done
) 200>/tmp/test.pid

文件确实被锁定了:

~$ ./lock.sh &
[2] 16803
~$ lsof /tmp/test.pid
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 26002 admin 200w REG 8,5 0 584649 test.pid
sleep 26432 admin 200w REG 8,5 0 584649 test.pid

最佳答案

fcntlflock 锁彼此不可见。

这对您的用例来说是个大问题,因为您在 shell 脚本中使用的 flock 实用程序依赖于 flock 语义:shell 脚本运行一个 flock 子进程,它锁定一个继承的文件描述符然后退出。 shell 保持该文件描述符打开(因为重定向是针对整个命令序列的)直到它想要释放锁。

该计划不能与 fcntl 一起使用,因为 fcntl 锁不在进程之间共享。如果有一个与 flock 相同但使用 fcntl 的实用程序,锁将过早释放(只要子进程退出)。

为了协调 perl 进程和 shell 脚本之间的文件锁,您可以考虑的一些选项是:

  • 将 shell 脚本移植到 zsh 并使用 zsh/system 模块中的 zsystem flock 内置(注意:在它声明的文档中使用 fcntl 尽管它的名字是 flock)
  • 用perl重写shell脚本
  • 只需在 perl 脚本中使用 flock(放弃字节范围锁定和“get locker PID”功能 - 但您可以通过阅读 /proc/locks 在 Linux 上模拟它)
  • 用 C 编写您自己的 fcntl 实用程序以用于 shell 脚本(使用模式会有所不同 - shell 脚本必须将其置于后台,然后稍后将其杀死以解锁 - 它会需要某种方式来告诉父进程何时获得或未能获得锁,这将很难,因为它现在是异步发生的......也许使用某些 shell 具有的 coprocess 功能)。
  • 从 shell 脚本运行一个小的 perl 脚本来进行锁定(将需要与专用 fcntl 实用程序所需的相同后台处理)

有关不同类型锁的功能的更多信息,请参阅 What is the difference between locking with fcntl and flock .

关于linux - 为什么 File::FcntlLock 的 l_type 总是 "F_UNLCK"即使文件被锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42253045/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com