[我有一個非常困難的時間來實現線程/進程安全的解決方案來獲取文件鎖使用Linux上的Python 3(我不在乎關於便攜式解決方案,因爲我工作的程序使用了大量的Linux內核獨佔集裝箱技術)。]尋找可靠的python進程同步技術(Linux不可移植)
閱讀http://apenwarr.ca/log/?m=201012#13後,我決定用fcntl.lockf()
鎖定過程獨佔訪問的文件和寫的以下功能:
import contextlib as Contextlib
import errno as Errno
import fcntl as Fcntl
import os as Os
@Contextlib.contextmanager
def exclusiveOpen(filename,
mode):
try:
fileDescriptor = Os.open(filename,
Os.O_WRONLY | Os.O_CREAT)
except OSError as e:
if not e.errno == Errno.EEXIST:
raise
try:
Fcntl.lockf(fileDescriptor,
Fcntl.LOCK_EX)
fileObject = Os.fdopen(fileDescriptor,
mode)
try:
yield fileObject
finally:
fileObject.flush()
Os.fdatasync(fileDescriptor)
finally:
Os.close(fileDescriptor)
除此之外,我確定,它是在正確的(爲什麼不阻止在Fcntl.lockf(fileDescriptor, Fcntl.LOCK_EX)
?),讓我感到不安的部分最多,是獲取fileDescriptor
的地方 - 如果文件不存在,它會被創建......但是發生了什麼,如果兩個進程同時執行這個部分?兩個線程都嘗試創建文件時,沒有競爭條件的機會嗎?如果是這樣,一個人怎麼可能阻止 - 當然不是與另一個鎖文件(?),因爲它必須以相同的方式創建(?!?!)我迷路了。任何幫助是極大的讚賞。
更新:發表了另一種解決根本問題的方法。我在這種方法中看到的問題是,過程名稱不能等於現有UNIX域套接字(可能由另一個程序創建)的名稱 - 我正確嗎?
你的FreeBSD的lockf塊? – MCH
@MCH好吧,我不能重現一個競爭條件,但我剛開始2個進程,在兩個文件中打開相同的文件(但是使用'O_RDWR'而不是'O_RDONLY'),並首先鎖定。當我嘗試在第二個鎖中取鎖時,它會被阻塞,直到第一個進程釋放鎖或關閉文件。一旦它獲得了鎖,它就會阻止任何其他嘗試採取它的進程。 –