11

複数のWindowsコンピューターで共有されているネットワークドライブ(Z:\)があります。このネットワークドライブでファイルを作成/削除するだけでクロスマシンロックを実装することは可能ですか?

たとえば、2台のコンピューターAとBが、同時にIDが123の共有リソースに書き込みたいとします。

コンピュータの1つ、たとえばAは、空のファイルZ:\ locks \ 123を作成することにより、最初にリソースをロックします。Bは、「123」という名前のロックファイルがあることを確認すると、リソース123が他の誰かによって使用されていることを認識しているため、AがZ:\ locks \ 123を削除してから、資源。

マルチスレッドのクリティカルセクションのようなものですが、複数のマシンで実行したいと思います。

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)

第二に(そしてこれが「一種の」出てくるところです)、あなたは錠を持っている人が死んだときに気づくための何らかの方法が欲しいでしょう。これを行う簡単な方法の1つは、ロックディレクトリ内のファイルをときどき更新することです。その後、クライアントがファイルがしばらく更新されていないことに気付いた場合、クライアントはディレクトリを削除して、自分でロックを取得しようとすることができます。

于 2012-06-06T04:17:41.020 に答える
2

これは、期待したほどうまく機能しません。ネットワークドライブがなくなるなど、他の問題が発生します。その場合、すべてのプロセスがスタックするか、誰もロックを保持していないと見なされます。

ZooKeeperのようなものを調べることをお勧めします。同期ロックを作成し、ネットワーク障害が発生した場合に回復することができます。分散ロックの背後にあるフレームワークは、ネットワークドライブにファイルを作成するよりもはるかに複雑です。

于 2012-06-06T04:26:51.343 に答える