2016-04-14 38 views
1

我有一個函數myfunc,它在並行處理中被調用。當我讓多個進程共享相同的目標文件夾時,它們全部並行調用myfunc並檢查目標文件夾的存在。如果它已經存在,沒問題。但是,如果在啓動腳本之前該文件夾不存在,那麼第一個進程將進入if塊並創建該文件夾。另一方面,如果在同一時間「幾乎」阻止,將會有另一個進程進入相同的狀態,會發現該文件夾不存在,並且將嘗試創建它,而第一個進程實際上正在創建它,或者已經做到了。所以在某個時候會有一個OSError告訴文件夾已經存在。在多處理時正確檢查文件存在

是否有一個乾淨的方式來處理這個問題,而多處理?在啓動我的進程之前,我正考慮在功能myfunc之外處理目標文件夾。爲了知識的緣故,找到使用多處理的解決方案會很好。爲解決併發問題

import os, sys 

def myfunc(file_names, destination=None, file_permission=None, verbose=False): 
    absPath = os.path.abspath(file_names[0]) 
    baseName = os.path.basename(absPath) 
    dirName = os.path.dirname(absPath) 


    destination_folder = "/default/destination" if destination is None \ 
     else os.path.abspath(destination) 

    if not os.path.isdir(destination_folder): 
     os.mkdir(destination_folder) 
     os.chmod(destination_folder, file_permission) 
     if verbose: 
      print "Created directory", destination_folder 
+0

那麼,趕上例外? – BlackBear

回答

0

使用Lockthreading模塊:

import os, sys 
from threading import Lock 

def myfunc(lock, ...): 
    ... do stuff as usual ... 

    with lock: 
     destination_folder = "/default/destination" if destination is None \ 
      else os.path.abspath(destination) 

    ... do everything else as usual ... 

if __name__ == "__main__": 
    my_lock = Lock() 
    myfunc(my_lock, ...) 
+1

如果使用'multiprocessing'(按照標題),則使用相應的'multiprocessing.Lock'。 –

1

檢查文件/文件夾的存在,並採取基於結果的行動是在大多數情況下根本錯誤的,因爲即使你不是多處理,你不知道計算機上還在運行着什麼。也很難保證別人以後不會運行多個流程副本,即使您原本不打算這樣做。

最健壯的方法是始終嘗試創建文件夾,並默默地忽略「但已存在」錯誤。 (不要忽略其他錯誤,比如「但你沒有這個權限」!)即使你在開始多處理之前做了一次檢查,這仍然是最好的方式。

+0

您是否認爲應該使用捕捉異常和鎖的組合?我實際上不知道你和Th3an0maly之間哪個答案最適合。 – kaligne

+0

爲了保持健壯,你必須抓住例外。在一般情況下,即使您的鎖是完美的,另一個程序可能會意外地從您下方更改文件或文件夾。完成之後,您可以評估是否還使用鎖或條件增加了價值。肯定有地方他們會有用,但我不認爲這是其中的一個地方。一旦發現異常,鎖定會增加此解決方案的複雜性,而不會提供任何額外的安全性。 – GrandOpener