如何文件锁定整个目录?

How to filelock an entire directory?

我想锁定一个目录及其内容,只允许一个进程写入其中。 为此,我使用了 Portalocker 库和一个名为 .lock

的文件
from pathlib import Path
import os
import portalocker as pl

DIRECTORY = Path('./protected')
p_lock = DIRECTORY / '.lock'
with pl.Lock(p_lock, 'w', timeout=10) as lock:
    # Writing pid to lock
    print(os.getpid(), file=lock)
    lock.flush()

    # do things that write to some files
    # inside DIRECTORY

    # Remove lock file
    p_lock.unlink()

只要所有进程执行相同的代码,就不会有两个进程在临界区。这没有造成任何问题,但现在我想进行 reader 处理。

from pathlib import Path
import os
import portalocker as pl

DIRECTORY = Path('./protected')
p_lock = DIRECTORY / '.lock'
with pl.Lock(p_lock, 'r', timeout=10):
    # do things

这会抛出一个 FileNotFoundError: [Errno 2] No such file or directory: './protected/.lock',因为当编写器完成时文件被删除。

如何确保一个进程正在写入,或者多个进程正在读取to/from一个目录?

Note: There is one writer process, and multiple readers (threads spawned from the same process, but not the same as the writer)

这是 portalocker 如何处理文件的问题 - 它尝试 open 它们,在 'w' 模式下打开 non-existing 文件时有效,但在 [=14] 下失败=]模式。

您的解决方案是手动创建文件(永远不要删除它,这是个坏主意)。

作者:

with pl.Lock(p_lock, 'w'):
    # do things
    # don't remove the p_lock file

Reader:

p_lock.touch(exist_ok=True)
with pl.Lock(p_lock, 'r', flags=pl.LockFlags.SHARED | pl.LockFlags.NON_BLOCKING):
    # do things
    # don't remove the p_lock file

(并且不要费心将 PID 写入文件,除非它是为了您自己的调试目的)