2016-09-28 56 views
0

雖然執行代碼片段X,但不應執行片段Y,並且執行Y時不應執行X.如果正在執行另一個,則應暫停X和Y.使用建議文件鎖限制併發進程

然而任何數量的進程或線程被允許同時執行碼X.

約並行執行多於一個Y什麼?它也應該暫停,直到Y的另一個實例被執行或死於錯誤「不能並行執行多個Y」。

這可以用Unix諮詢文件鎖來實現嗎?我想我應該將當前執行的X的數量寫入文件中(類似於引用計數)。或者,也許我需要兩個文件:一個用於存儲執行X的併發進程的數量,另一個用於鎖定第一個文件?現在我們來嘗試構造算法。

請注意,我用Python編寫。

+0

注意,X在實施Y的功能我真正的問題是修改數據庫的代碼,Y是數據庫恢復過程,如果數據在某種程度上不一致,則需要使用 – porton

+0

如果存在Y請求掛起是否允許X請求繼續進行,還是一直持續到Y被處理?是否還有其他共享/飢餓問題需要擔心(例如,阻止X請求的Y請求太多)?這幾乎是標準的'讀者和作者'相互排斥或鎖定的東西 - 基本併發理論。只要流程合作,就可以通過諮詢鎖定來完成。 –

+0

@JonathanLeffler你是什麼意思的「待定」?如果Y被執行,所有X必須等待。我需要一個或兩個諮詢鎖嗎? – porton

回答

0

這可以用一個鎖來解決,因爲有兩種諮詢文件鎖:獨佔和共享。 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") 

,只是添加@task.sequential(LOCK_SH)到功能實現X和@task.sequential(LOCK_EX)