`flock -u` 实际上是做什么的?

问题描述

我正在使用命令 flock,它获取和释放文件锁定。例如,如果我运行

flock /tmp/mylock true

然后它立即退出,大概是获取然后释放锁。如果我跑

flock /tmp/mylock sleep 100

然后它会延迟 100 秒,再次获取和释放锁。而且,如果我在两个单独的 shell 中运行以下命令:

flock /tmp/mylock sleep 100

flock /tmp/mylock true

然后第二个命令被阻塞,因为它在第一个命令运行时无法获得锁。 sleep 100 完成并释放锁后,第二个命令将运行并退出。一切都很好。

问题来了。如果在这 100 秒的延迟期间,我在第三个 shell 中运行以下命令:

flock -u /tmp/mylock true

然后呢? flock 的手册页说:

   -u,--unlock
          Drop  a  lock.   This  is  usually not required,since a lock is
          automatically dropped when the file is closed.  However,it  may
          be  required  in special cases,for example if the enclosed com-
          mand group may have forked a background process which should not
          be holding the lock.

所以,这应该解除锁定,这应该允许 flock /tmp/mylock true 运行,对吗? (我也猜测 flock /tmp/mylock sleep 100 会立即退出,但这是推测。)

会发生什么?没有什么。 flock -u /tmp/mylock true 立即退出,但 flock /tmp/mylock true 继续被阻止,而 flock /tmp/mylock sleep 100 继续退出

flock -u /tmp/mylock <command> 实际上是做什么的?

(所有示例均在 Ubuntu 18.04 上测试。)

解决方法

这是一个示例,-u 使用文件描述符 9 打开文件 mylock,成功解锁 9 以便后台 flock mylock 可以继续。 请注意,flock 9 不能也有命令,因为在这种情况下,“9”被视为文件名,而不是 fd。

bash -s <<\!  9>mylock 2>&1 |
 flock 9; echo gotlock1
 flock 9; echo gotlock2
 9>&- flock mylock bash -c 'echo start_sleep;sleep 8; echo end_sleep' &  
 sleep 2
 flock -u 9; echo unlock; sleep .1
 flock 9; echo gotlock3
!

awk '{t2=systime(); if(t1==0)t1=t2; printf "%2d %s\n",t2-t1,$0; t1=t2}'

第一行让 bash 在打开 fd 9 后运行以下几行,但也通过最后看到的 awk 脚本管道 stdout 和 stderr。这只是为了用行的时间来注释输出。结果是:

 0 gotlock1
 0 gotlock2
 2 unlock
 0 start_sleep
 8 end_sleep
 0 gotlock3

这显示了前 2 个 flock 9 命令立即运行。然后 flock mylock 命令在后台运行,在关闭 fd 9 之后只为这一行。例如,该命令可以从第二个窗口运行。输出显示它挂起,因为我们没有看到 start_sleep。这意味着前面的 flock 9 确实获得了排他锁。

然后输出显示,在 sleep 2flock -u 9 之后,我们得到 unlock 回声,然后后台命令才获得锁并启动它的 sleep 8

主脚本立即执行 flock 9,但输出显示直到后台脚本在 8 秒后以 end_sleep 结束,并且主脚本输出 gotlock3 后才会继续执行。

lslocks 命令有时会显示 2 个对锁感兴趣的进程。 * 表示等待:

COMMAND           PID  TYPE SIZE MODE  M      START        END PATH
flock           23671 FLOCK   0B WRITE* 0          0          0 /tmp/mylock
flock           23655 FLOCK   0B WRITE  0          0          0 /tmp/mylock

但是它本身并没有显示第一个 flock 9 的结果,大概是因为没有带锁的进程,即使文件确实被锁定,正如我们在后台作业无法继续时看到的那样。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...