Python:锁定目录

gue*_*tli 4 python locking

AFAIK 此代码可用于锁定目录:

class LockDirectory(object):
    def __init__(self, directory):
        assert os.path.exists(directory)
        self.directory = directory

    def __enter__(self):
        self.dir_fd = os.open(self.directory, os.O_RDONLY)
        try:
            fcntl.flock(self.dir_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except IOError as ex:
            if ex.errno != errno.EAGAIN:
                raise
            raise Exception('Somebody else is locking %r - quitting.' % self.directory)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.dir_fd.close()
Run Code Online (Sandbox Code Playgroud)

但是根据这个问题的答案锁定目录是不可能的:Python: Lock a directory

上面的代码有什么问题?

我只需要支持当前的 linux 版本。没有 Windows、Mac 或其他 unix。

obg*_*naw 5

我稍微更改了您的代码,return self像大多数上下文管理一样添加,然后使用dup(),第二个上下文管理将失败。解决方案很简单,取消注释fcntl.flock(self.dir_fd,fcntl.LOCK_UN)

用于打开文件的模式与群集无关。

你不能蜂拥而至 NFS。

import os
import fcntl
import time
class LockDirectory(object):
    def __init__(self, directory):
        assert os.path.exists(directory)
        self.directory = directory

    def __enter__(self):
        self.dir_fd = os.open(self.directory, os.O_RDONLY)
        try:
            fcntl.flock(self.dir_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
        except IOError as ex:             
            raise Exception('Somebody else is locking %r - quitting.' % self.directory)
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # fcntl.flock(self.dir_fd,fcntl.LOCK_UN)
        os.close(self.dir_fd)

def main():
    with LockDirectory("test") as lock:
        newfd = os.dup(lock.dir_fd)
    with LockDirectory("test") as lock2:
        pass

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)