文件锁定未按预期工作

6 投票
3 回答
3874 浏览
提问于 2025-04-16 14:04

我有一个继承自Thread的类,这个类应该一次只能运行一个实例(跨进程)。为了实现这个功能,我打算使用文件锁。以下是我代码的一部分:

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)

我原本期待lockf这个调用会在一个Scanner线程已经在运行时抛出一个异常,这样就根本不会初始化这个对象。然而,我在终端看到的是:

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线程同时在运行,并没有抛出异常。我知道我这里肯定漏掉了什么基本的东西,但我就是搞不清楚是什么。有人能帮忙吗?

3 个回答

0

在使用flock的时候,我还需要这样打开文件:

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

否则就不行。

2

你用 r+ 打开锁文件,这样会把之前的文件内容清空,然后创建一个新的文件。每个线程都在锁定不同的文件。

可以试试用 w 或者 r+a

4

最后我自己找到了解决办法。就是用 fcntl.flock() 代替 fcntl.lockf(),参数完全一样。不太明白为什么这样会有不同的效果。

撰写回答