【问题标题】:File lock not working as expected文件锁未按预期工作
【发布时间】:2011-03-20 16:44:34
【问题描述】:

我有一个Thread-extending 类,它应该一次只运行一个实例(跨进程)。为了实现这一点,我正在尝试使用文件锁。以下是我的一些代码:

class Scanner(Thread):

  def __init__(self, path):
    Thread.__init__(self)
    self.lock_file = open(os.path.join(config.BASEDIR, "scanner.lock"), 'r+')
    fcntl.lockf(self.lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)

  # Stuff omitted

  def run(self):
    logging.info("Starting scan on %s" % self.path)

    # More stuff omitted

    fcntl.lockf(self.lock_file, fcntl.LOCK_UN)

如果Scanner 线程已经在运行并且根本没有初始化对象,我希望lockf 调用会引发异常。但是,我可以在终端中看到:

INFO:root:Starting scan on /home/felix/Music
INFO:root:Starting scan on /home/felix/Music
INFO:root:Scan finished
INFO:root:Scan finished

这表明两个Scanner 线程同时运行,没有抛出异常。我确定我在这里遗漏了一些非常基本的东西,但我似乎无法弄清楚那是什么。有人可以帮忙吗?

【问题讨论】:

    标签: python file-io filelock


    【解决方案1】:

    最后自己找到了解决方案。它是使用fcntl.flock() 而不是fcntl.lockf(),具有完全相同的参数。不知道为什么会有所作为。

    【讨论】:

    • 很高兴您发现了这一点,但这很奇怪。从历史上看, fcntl 更可靠,尽管flock() 不再是 fcntl 包装器,这可能是由于 python 处理线程的方式。请务必接受您自己的答案!
    • 确实很奇怪。我看不出 Python 的线程会有什么问题——run() 中的进程需要一段时间(~10 秒),在这段时间内我可以轻松地启动另一个 6-7 个线程来做同样的事情,当使用lockf() 打电话。但是,如果我不使用LOCK_NB 标志,它会等待另一个线程释放锁。我会接受我自己的答案,什么时候让我:)
    • 我遇到了同样的问题。它不能与lockf() 一起正常工作,但更改为flock() 有效。我在 Ubuntu 14.04(在 Docker 中运行)上使用 Python 2.7.11。
    【解决方案2】:

    您正在使用r+ 打开锁定文件,这将擦除以前的文件并创建一个新文件。每个线程都在锁定不同的文件。

    使用wr+a

    【讨论】:

    • 您是否在某处关闭该文件?基本上,您要么以某种方式打开两个不同的文件,要么在某处释放锁。您对fcntl.lockf 的调用在语法上是正确的,它应该按照您的预期进行。您可能想发布完整的代码。
    • 我不会在任何地方关闭文件,而是将它保存在实例变量中,因此不会被垃圾收集。我认为lockf() 的问题在于它锁定了文件的一部分,而不是整个文件本身(尽管没有参数,这就是它应该做的),并且当你给它一个空的文件。我没有试图证明这个理论(通过在文件中写一些东西)。如果我愿意,我会更新我的答案。
    【解决方案3】:

    除了使用flock,我还必须像这样打开文件:

    fd = os.open(lockfile, os.O_CREAT | os.O_TRUNC | os.O_WRONLY)
    

    否则它不起作用。

    【讨论】:

      猜你喜欢
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      • 2016-02-04
      相关资源
      最近更新 更多