2016-09-28 5 views
0

コードのフラグメントXが実行される間、フラグメントYは実行されてはならず、Yが実行されると、Xは実行されません。代わりに、現在実行されている別のものがあれば、XとYを一時停止する必要があります。アドバイザリファイルロックによる並行プロセスの制限

ただしプロセスまたはスレッドの任意の数を同時に並行して複数のYを実行についてコードX.

何を実行するために許可されて?また、Yの別のインスタンスが実行されるか、「複数のYを同時に実行できません」というエラーで終了するまで待機する必要があります。

これはUnixのアドバイザリファイルのロックで実装できますか?私はファイルに現在実行されているXの数を書くべきだと思う(参照カウントと同様)。あるいは、私は2つのファイルが必要です:1つはXを実行している同時プロセスの数を格納し、もう1つは最初のものをロックするためです。ここでアルゴリズムを構築してみましょう。

私はPythonで書いています。

+0

注意を実装する機能にXと@task.sequential(LOCK_EX)を実装する機能に@task.sequential(LOCK_SH)を追加します実際の問題は、DBを変更するコードであり、YはDB復旧手順です。データが何らかの形で不整合になった場合に必要です。 – porton

+0

Yリクエストの保留がある場合進行中のXリクエストが許可されているか、Yが処理されるまで保持されますか?心配する他の共有/飢餓の問題がありますか(例えば、Xリクエストを防ぐYリクエストが多すぎます)?これはすべて、かなり標準的な「読者と作家の相互排除またはロックのもの - 基本的な並行性理論」です。プロセスが協調している限り、アドバイザリロックを使用して行うことができます。 –

+0

@JonathanLeffler「保留中」とはどういう意味ですか? Yを実行すると、すべてのXが待機する必要があります。 1つまたは2つのアドバイザリロックが必要ですか? – porton

答えて

0

これは、2種類のアドバイザリファイルロックが存在するため、1つのロックで解決できます。 Yは排他ロックを取得し、Xは共有ロックを取得します。ここで

は、実際のコードです:

class SequentialTask: 
    def __init__(self, lock_file): 
     self.lock_file = lock_file 

    def sequential(self, lock_mode): 
     def sequential_decorator(func): 
      #@wraps(func) # TODO: doesn't work 
      def func_wrapper(*args, **kwargs): 
       with open(self.lock_file, 'w') as file: 
        logger = logging.getLogger(__name__) 
        logger.debug("Locking a sequential request...") 
        flock(file, lock_mode) 
        try: 
         return func(*args, **kwargs) 
        finally: 
         logger.debug("Unlocking a sequential request...") 
         # unlink(self.lock_file) # Don't do: http://stackoverflow.com/q/17708885/856090 
         flock(file, LOCK_UN) 
         # unlink(self.lock_file) # Don't do: open but unlocked file may be deleted. 
      return func_wrapper 
     return sequential_decorator 

その後

task = SequentialTask(VAR_DIR+"/groups-modify.lock") 

とちょうどX私の中にいることY.

関連する問題