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()
但是根据此问题的答案,无法锁定方向:Python: Lock a directory
上面的代码有什么问题?
我只需要支持当前的linux版本。没有Windows,Mac或其他Unix。
答案 0 :(得分:2)
如果您只需要一个 read 锁,那么您所拥有的代码中只有一个小错误。在目录上获得读取锁定是完全可行的。
您需要更改__exit__
函数以使用os.close()
关闭文件描述符;文件描述符只是一个整数,并且整数没有.close()
方法:
def __exit__(self, exc_type, exc_val, exc_tb):
os.close(self.dir_fd)
对于那些认为自己做不到的人来说,通常的困惑是那些尝试使用open()
函数的人。 Python不允许您使用该功能打开目录节点,因为为目录创建Python文件对象没有意义。也许有一种假设是,您希望操作系统通过该锁来强制对目录的访问(与咨询锁相反,在协作访问之前,协作进程同意先获取该咨询锁)。
所以不,如果您想要的只是一个咨询锁,那么代码没有任何问题,并且只在Linux上有效。
我将从代码中删除directory
区别。该锁将在您具有读取权限的任何路径上起作用。它不是目录专有的。
锁定目录的不利之处在于,这没有给您存储锁定元数据的位置。尽管lsof
可以为您提供锁的当前所有者的PID,但是您可能希望与该锁通信一些其他信息,以帮助排除故障或自动解除锁。 .lock
文件或符号链接可让您记录其他信息。例如,Mercurial将使用主机名,PID名称空间标识符(仅Linux)和目标名称中的PID创建符号链接。您可以原子地创建这样的符号链接,而将数据写入文件时将需要以临时名称和重命名来创建文件。
答案 1 :(得分:2)
我稍微更改了代码,像大多数上下文管理一样添加return self
,然后使用dup()
,第二个上下文管理将失败。解决方案很简单,无需注释fcntl.flock(self.dir_fd,fcntl.LOCK_UN)
< / p>
用于打开文件的模式与群集无关。
您不能蜂拥到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()
答案 2 :(得分:0)
我在这里找到了答案:Python: Lock directory
可以使用以下方式锁定目录:
fcntl.flock(self.dir_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
当然,这是一把锁,在游戏中玩的每个代码都需要首先检查。
AFAIK,这称为“咨询锁定”。
答案 3 :(得分:-1)
我建议您使用一个简单的锁定文件。正如评论(How to lock a directory between python processes in linux?)中的问题所暗示的那样,与文件相对,没有目录的锁定机制。
锁定文件在Linux上左右使用,它们非常透明且易于调试,因此我就顺其自然了。
我正等着被挑战!