Bash中的Lockfiles:一次运行两个副本时文本文件繁忙

时间:2015-04-20 21:41:45

标签: linux bash shell

我有一个Bash脚本需要在运行时锁定文件以进行独占读/写。在此期间,运行相同脚本的任何其他副本应该挂起,直到锁定被释放(这应该很快)。

#!/bin/bash

trap "rm -f /tmp/.lock; exit" 0 1 2 3 15

(
    flock -x 100 

    # Stuff happens here...

) 100>/tmp.lock

这有点起作用。但不是在这些条件下:

  1. 启动脚本副本#1
  2. 启动脚本副本#2
  3. 脚本副本#2之前的脚本副本#1
  4. 此时,我收到错误:

    rm: cannot remove '/tmp/.lock': Text file busy
    

    我认为我是如何用陷阱清理的,所以任何帮助都会非常感激。谢谢!

1 个答案:

答案 0 :(得分:4)

只要持有该锁的任何程序可能正在运行或试图运行,

就不会尝试“清理”flock风格的锁文件。

请记住,锁定保存在 inode 上,而不是文件名。删除目录条目会将先前在该位置的inode与其名称分离,从而允许该名称引用不同的inode。

考虑以下情况:

  1. 程序A持有锁。
  2. 程序B打开锁定文件并尝试锁定它,阻塞直到程序A完成锁定。
  3. 节目A结束;关闭锁;并删除锁文件。
  4. 程序B 仍然保留已删除锁文件的句柄。当程序A关闭锁(或退出,释放其文件句柄并因此锁定)时,程序B能够继续运行,将该句柄保持为锁定。
  5. 程序C尝试抓住锁。 即使程序B仍在运行,由于程序A删除了程序B保存句柄的程序B,因此允许程序C同时运行。
  6. 程序B退出,删除程序C创建的锁文件,而程序C仍在运行。

  7. 应该将Flock文件锁定文件视为从文件系统命名空间到文件锁定命名空间的映射。这些映射不需要也不应该“清理”。您可能希望考虑操作系统的文件系统层次结构标准是否为这些文件提供了生存的位置,例如/var/lock,或tmpfs上的某个位置(其中“清理”将隐式发生 - 并且安全 - - 重启时。)