9

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

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

空のファイルZ:\ locks \ 123を作成することによって、コンピュータの1つ、たとえばAがリソースをロックします。 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) 

:ここでは私が思いついたものです。

また、質問はです。共有ストレージにクロスマシン・ロック・メカニズムを実装することは可能ですか?

答えて

5

...のようなものです。

まず、ロックファイルの代わりにロックディレクトリを作成する必要があります。ディレクトリの作成(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つは、ロックディレクトリ内のファイルを時々更新することです。その後、クライアントがしばらくの間更新されていないことをクライアントが認識すると、ディレクトリを削除してロックを取得しようとします。

+1

タイムアウトの追加はどうですか?すなわち、例えば60秒の時間の後、自動的にロックが解除される。ロッキング時間がこのタイムアウトを超えないと仮定します。 time.time() - os.path.getctime( "Z:\ my_lock")でロック時間を取得して、ロックが遅れていないかどうかを調べることができます。 – eliang

2

これはあなたの希望に近いほどうまく機能しません。ネットワークドライブがなくなるなどのその他の問題が発生します。この場合、すべてのプロセスが停止したり、誰もロックを保持していないと考えられます。

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

+0

私はMemcacheやBeanstalkのようなキューソフトウェアを考えていました。 – aitchnyu

関連する問題