【问题标题】:Perl File::NFSLock fails to acquire lock with error EACCESSPerl File::NFSLock 无法获取锁并出现错误 EACCESS
【发布时间】:2021-03-08 06:22:35
【问题描述】:

我在 NFS 挂载上有一个文件,该文件针对对其执行的每项操作都被锁定和解锁。 最初我使用flock(filehandle, LOCK_EX|LOCK_NB),但使用I/O Error 失败。
在浏览多个论坛时,我找到了使用File::NFSLock 锁定/解锁 NFS 共享上的文件的解决方案。但是,NFSLock 在第一次尝试锁定和解锁文件时成功,但是当 2 个进程同时尝试访问锁定时,它会失败并出现 EACESS 错误。
代码如下:

  1. Process 1 使用以下代码获得了锁,完成后也释放了锁:
    if ($lock = new File::NFSLock {
      file      => $handle,
      lock_type => LOCK_EX|LOCK_NB,
    }) {
  1. 现在使用fork 命令(Process 2Process 3)生成了两个进程。当Process 2 尝试在步骤 1 中使用相同的上述代码锁定同一个文件时,文件锁定失败并出现错误Permission Denied。在Process 3 尝试获取锁定 15 秒后,它也因Permission Denied 错误而失败。
    当我对文件执行fuser -v 时,我可以看到打开文件进行写入的2 个进程ID(Process 2Process 3)。

互联网上很少有文件表明The lock cannot be set because it is blocked by an existing lock on the file. Some systems use EAGAIN in this case, and other systems use EACCES 但在我的情况下似乎并非如此,因为Process 1 已释放锁定。
另请注意,所有 3 个进程都是从同一个脚本生成的,因此不应该存在不同用户尝试获取锁的问题。

谢谢!

【问题讨论】:

  • 请提供完整的错误信息。 new File::NFSLock 不会产生您提供的错误消息。
  • 给你 - [无法打开“FileHandle=GLOB(0x800ac68).tmp.2810.31272.5622”[权限被拒绝]]
  • 1) 如果问题需要澄清,则应进行编辑。 2) 您传递的是文件句柄,而不是 file 参数的文件路径。也许不仅仅是问题,而是第一个问题。 3) 现在在床上。
  • 相同的代码适用于一个进程而不适用于其他进程。所以我怀疑这可能是一个问题,无论如何让我尝试使用路径并更新它。
  • 嘿@ikegami,救世主,用路径替换手柄..非常感谢!

标签: multithreading perl locking nfs


【解决方案1】:

File::NFSLock 的file 参数需要一个文件路径——而不是文件句柄。用文件路径替换文件句柄解决了这个问题。

if ($lock = new File::NFSLock {
  file      => $path,             # Previously, I used file handle here.
  lock_type => LOCK_EX|LOCK_NB,
}) {

【讨论】:

    猜你喜欢
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 2022-07-30
    • 2023-03-15
    相关资源
    最近更新 更多