Ich muss eine Datei zum Schreiben in Python sperren. Es wird von mehreren Python-Prozessen gleichzeitig darauf zugegriffen. Ich habe einige Lösungen online gefunden, aber die meisten scheitern für meine Zwecke, da sie oft nur auf Unix oder Windows basieren.
python
file-locking
Evan Fosmark
quelle
quelle
Hier gibt es ein plattformübergreifendes Dateisperrmodul: Portalocker
Obwohl, wie Kevin sagt, das Schreiben in eine Datei aus mehreren Prozessen gleichzeitig vermieden werden sollte, wenn dies überhaupt möglich ist.
Wenn Sie Ihr Problem in eine Datenbank einbinden können, können Sie SQLite verwenden. Es unterstützt den gleichzeitigen Zugriff und verwaltet seine eigenen Sperren.
quelle
Die anderen Lösungen zitieren viele externe Codebasen. Wenn Sie es lieber selbst tun möchten, finden Sie hier einen Code für eine plattformübergreifende Lösung, die die entsprechenden Tools zum Sperren von Dateien auf Linux / DOS-Systemen verwendet.
Nun
AtomicOpen
kann in einen verwendet werden ,with
Block , in dem man normalerweise eine Verwendungopen
Aussage.WARNUNG: Wenn die Ausführung unter Windows und Python vor dem Aufruf von exit abstürzt , bin ich mir nicht sicher, wie das Sperrverhalten aussehen würde.
WARNUNG: Die hier bereitgestellte Verriegelung ist nicht absolut, sondern nur eine Empfehlung. Alle potenziell konkurrierenden Prozesse müssen die Klasse "AtomicOpen" verwenden.
quelle
unlock_file
Datei unter Linux sollte nichtfcntl
wieder mit demLOCK_UN
Flag aufrufen ?__exit__
dirclose
außerhalb des Schlosses nachunlock_file
. Ich glaube, die Laufzeit könnte Daten während spülen (dh schreiben)close
. Ich glaube, man mussflush
undfsync
unter dem Schloss, um sicherzustellen, dass während des Schlosses keine zusätzlichen Daten geschrieben werdenclose
.flush
undfsync
. Ich habe die beiden Zeilen hinzugefügt, die Sie vor dem Anruf vorgeschlagen habenunlock
. Ich habe erneut getestet und die Rennbedingung scheint gelöst zu sein.Ich bevorzuge lockfile - Plattformunabhängiges Sperren von Dateien
quelle
Ich habe nach verschiedenen Lösungen gesucht, um dies zu erreichen, und meine Wahl fiel auf oslo.concurrency
Es ist mächtig und relativ gut dokumentiert. Es basiert auf Verbindungselementen.
Andere Lösungen:
quelle
filelock
(Zuletzt veröffentlicht: 18. Mai 2019 zum Zeitpunkt des Kommentars)Das Sperren ist plattform- und gerätespezifisch, aber im Allgemeinen haben Sie einige Optionen:
Für all diese Methoden müssen Sie eine Spin-Lock-Technik (Retry-After-Failure) verwenden, um die Sperre zu erwerben und zu testen. Dies lässt zwar ein kleines Fenster für die Fehlersynchronisation, ist jedoch im Allgemeinen klein genug, um kein großes Problem zu sein.
Wenn Sie nach einer plattformübergreifenden Lösung suchen, sollten Sie sich besser über einen anderen Mechanismus bei einem anderen System anmelden (das nächstbeste ist die oben beschriebene NFS-Technik).
Beachten Sie, dass SQLite gegenüber NFS denselben Einschränkungen unterliegt wie normale Dateien. Sie können also nicht in eine SQLite-Datenbank auf einer Netzwerkfreigabe schreiben und die Synchronisierung kostenlos durchführen.
quelle
os.rename
ist jetzt in Win32 seit Python 3.3 atomarDie Koordinierung des Zugriffs auf eine einzelne Datei auf Betriebssystemebene ist mit allen möglichen Problemen behaftet, die Sie wahrscheinlich nicht lösen möchten.
Am besten haben Sie einen separaten Prozess, der den Lese- / Schreibzugriff auf diese Datei koordiniert.
quelle
flock
. Ein Ansatz, "Ihre eigenen Mutexe und einen Daemon-Prozess zu rollen, um sie zu verwalten", scheint ein ziemlich extremer und komplizierter Ansatz zu sein, um ihn zu lösen ... ein Problem, von dem Sie uns nicht wirklich erzählt haben, das aber nur beängstigend vorgeschlagen wurde.Das Sperren einer Datei ist normalerweise eine plattformspezifische Operation. Daher müssen Sie möglicherweise die Möglichkeit berücksichtigen, auf verschiedenen Betriebssystemen ausgeführt zu werden. Beispielsweise:
quelle
Ich habe an einer solchen Situation gearbeitet, in der ich mehrere Kopien desselben Programms aus demselben Verzeichnis / Ordner und Protokollierungsfehlern ausführe. Mein Ansatz war es, vor dem Öffnen der Protokolldatei eine "Sperrdatei" auf die Disc zu schreiben. Das Programm prüft vor dem Fortfahren, ob die "Sperrdatei" vorhanden ist, und wartet, bis es an der Reihe ist, wenn die "Sperrdatei" vorhanden ist.
Hier ist der Code:
BEARBEITEN --- Nachdem ich über einige der obigen Kommentare zu veralteten Sperren nachgedacht hatte, bearbeitete ich den Code, um eine Überprüfung auf Veraltetheit der "Sperrdatei" hinzuzufügen. Das Timing mehrerer tausend Iterationen dieser Funktion auf meinem System ergab einen Durchschnitt von 0,002066 ... Sekunden von kurz zuvor:
zu kurz danach:
Also dachte ich mir, ich werde mit dem Fünffachen dieses Betrags beginnen, um die Alterung anzuzeigen und die Situation auf Probleme zu überwachen.
Als ich mit dem Timing arbeitete, stellte ich fest, dass ich ein bisschen Code hatte, der nicht wirklich notwendig war:
was ich unmittelbar nach der offenen Anweisung hatte, also habe ich es in dieser Bearbeitung entfernt.
quelle
Um die Antwort von Evan Fossmark zu ergänzen , finden Sie hier ein Beispiel für die Verwendung von Filelock :
Jeder Code innerhalb des
with lock:
Blocks ist threadsicher. Dies bedeutet, dass er beendet wird, bevor ein anderer Prozess Zugriff auf die Datei hat.quelle
Das Szenario sieht folgendermaßen aus: Der Benutzer fordert eine Datei auf, etwas zu tun. Wenn der Benutzer dieselbe Anforderung erneut sendet, informiert er den Benutzer darüber, dass die zweite Anforderung erst ausgeführt wird, wenn die erste Anforderung abgeschlossen ist. Deshalb benutze ich einen Sperrmechanismus, um dieses Problem zu lösen.
Hier ist mein Arbeitscode:
quelle
Ich habe eine einfache und funktionierende (!) Implementierung von Grizzled-Python gefunden.
Einfache Verwendung os.open (..., O_EXCL) + os.close () funktionierte unter Windows nicht.
quelle
Sie können Pylocker sehr nützlich finden. Es kann zum Sperren einer Datei oder zum Sperren von Mechanismen im Allgemeinen verwendet werden und kann von mehreren Python-Prozessen gleichzeitig aufgerufen werden.
Wenn Sie eine Datei einfach sperren möchten, funktioniert dies folgendermaßen:
quelle