11

我有一个由多台 Windows 计算机共享的网络驱动器 (Z:\)。是否可以通过简单地在此网络驱动器上创建/删除文件来实现跨机锁定?

例如,两台计算机 A 和 B 要同时写入 ID 为 123 的共享资源。

其中一台计算机,比如 A,首先通过创建一个空文件 Z:\locks\123 来锁定资源。当 B 看到有名为“123”的锁文件时,B 知道资源 123 正在被其他人使用,所以它必须等待 Z:\locks\123 被 A 删除才能访问资源。

这就像多线程中的关键部分,但我想在多台机器上进行。

我正在尝试在 Python 中实现。这是我想出的:

import os
import time


def lock_it(lock_id):

    lock_path = "Z:\\locks\\" + lock_id
    while os.path.exists(lock_path):
        time.sleep(5)  # wait for 5 seconds

    # create the lock file
    lock_file = open(lock_path, "w")
    lock_file.close()


 def unlock_it(lock_id):

     # delete the lock file
     lock_path = "Z:\\locks\\" + lock_id
     if os.path.exists(lock_path):
         os.remove(lock_path)

这将不起作用,因为可能有多个进程退出等待状态并同时创建锁定文件。

再次,问题是:是否可以在共享存储上实现跨机器锁定机制?

4

2 回答 2

8

... 有点。

首先,您应该创建一个锁定目录而不是锁定文件。如果目录已经存在,则创建目录(请参阅os.mkdir)将失败,因此您可以像这样获取锁:

while True:
    try:
        os.mkdir(r"z:\my_lock")
        return
    except OSError as e:
        if e.errno != 21: # Double check that errno will be the same on Windows
            raise
        time.sleep(5)

其次(这就是“某种”出现的地方)您需要某种方式来注意到持有锁的人何时死亡。一种简单的方法可能是让他们偶尔更新锁定目录中的文件。然后,如果客户端注意到文件有一段时间没有更新,他们可以删除目录并尝试自己获取锁。

于 2012-06-06T04:17:41.020 回答
2

这不会像您希望的那样工作。您还会遇到其他问题,例如网络驱动器消失,在这种情况下,您的所有进程要么被卡住,要么认为没有人持有锁。

我建议你研究类似ZooKeeper的东西。您将能够创建同步锁并在发生网络故障时恢复。分布式锁背后的框架比在网络驱动器上创建文件要复杂得多。

于 2012-06-06T04:26:51.343 回答