[Ich habe eine extrem schwierige Zeit, eine thread-/process-safe-Lösung zu implementieren, um eine Dateisperre mit Python 3 unter Linux zu erhalten (ist mir egal über portable Lösungen, da das Programm, an dem ich arbeite, die Linux-Kernel-exklusiven Container-Technologien nutzt.]Auf der Suche nach zuverlässigen Python-Prozess-Synchronisationstechniken (Linux nicht portierbar)
Nachdem ich http://apenwarr.ca/log/?m=201012#13 gelesen hatte, entschied ich mich, fcntl.lockf()
zu verwenden, um eine Datei für den prozessexklusiven Zugriff zu sperren und schrieb die folgende Funktion:
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)
von Apart, dass ich bin sicher, dass es in richtig (warum blockiert es nicht in Fcntl.lockf(fileDescriptor, Fcntl.LOCK_EX)
?), der Teil, der mich am meisten unbehaglich fühlt, ist, wo die fileDescriptor
erworben wird - wenn die Datei nicht vorhanden ist, wird es erstellt ... aber was ist los, wenn zwei Prozesse führen diesen Teil gleichzeitig aus? Gibt es keine Chance auf eine Race Condition, bei der beide Threads versuchen, die Datei zu erstellen? Und wenn ja, wie könnte man das vielleicht verhindern - schon gar nicht mit einer anderen Sperrdatei (?), Weil es auf die gleiche Weise erstellt werden müsste (?!?!) Ich bin verloren. Jede Hilfe wird sehr geschätzt.
UPDATE: Posted eine andere Herangehensweise an das zugrunde liegende Problem. Das Problem, das ich in diesem Ansatz sehe, ist, dass ein Prozedurname nicht mit dem Namen eines vorhandenen UNIX-Domänen-Sockets übereinstimmen muss (möglicherweise von einem anderen Programm erstellt) - stimme ich damit überein?
lockf Block auf Ihrem FreeBSD? – MCH
@MCH Nun konnte ich keine Race Condition reproduzieren, aber ich habe gerade 2 Prozesse gestartet, öffne die gleiche Datei in beiden (aber mit 'O_RDWR' anstelle von' O_RDONLY') und nimm die Sperre zuerst. Wenn ich versuche, die Sperre in der zweiten zu übernehmen, wird sie blockiert, bis der erste Prozess die Sperre aufhebt oder die Datei schließt. Und sobald es das Schloss erworben hat, blockiert es jeden anderen Prozess, der versuchen würde, es zu nehmen. –