創建文件夾我有一個urllib2的緩存模塊,其偶爾崩潰的原因如下代碼:賽條件在Python
if not os.path.exists(self.cache_location):
os.mkdir(self.cache_location)
是,通過的時間被執行的問題的第二行,該文件夾可以存在,並將錯誤:
File ".../cache.py", line 103, in __init__ os.mkdir(self.cache_location) OSError: [Errno 17] File exists: '/tmp/examplecachedir/'
這是因爲腳本是同時啓動無數次,我無法控制的第三方代碼。
的代碼(之前,我試圖修復bug),可以發現here, on github
我不能使用tempfile.mkstemp,因爲它解決了通過使用一個隨機命名的目錄(tempfile.py source here)的競爭條件,這將破壞緩存的目的。
我不想簡單地丟棄的錯誤,因爲同樣的錯誤,如果該文件夾的名稱作爲文件形式存在(不同的錯誤)引發errno的17錯誤,例如:
$ touch blah $ python >>> import os >>> os.mkdir("blah") Traceback (most recent call last): File "", line 1, in OSError: [Errno 17] File exists: 'blah' >>>
我不能使用threading.RLock
作爲從多個進程調用的代碼。
於是,我試着寫一個簡單的基於文件的鎖(that version can be found here),但是這有一個問題:它會創建鎖文件的上一級,所以/tmp/example.lock
爲/tmp/example/
,如果你使用/tmp/
作爲緩存目錄打破(如它試圖使/tmp.lock
)..
總之,我需要緩存urllib2
響應光盤。爲此,我需要以多進程安全的方式訪問已知的目錄(如果需要,可以創建它)。它需要在OS X,Linux和Windows上工作。
想法?我能想到的唯一替代解決方案是使用SQLite3存儲重寫緩存模塊,而不是文件。
可能!我認爲,正如我重新閱讀的問題,提交之前..我實現這個(http://github.com/dbr/tvdb_api/blob/468d9f816373b14ef3a483fca07e031b69fa62f9/cache.py#L103-114)並且會讓報告錯誤的人馬上進行測試。 – dbr
這似乎工作完美,謝謝! – dbr
@dbr:請注意,在第114行中,您希望'raise e',因爲它已經是'OSError'的一個實例。 http://github.com/dbr/tvdb_api/blob/468d9f816373b14ef3a483fca07e031b69fa62f9/cache.py#L114 – nosklo