Sperren Sie eine Datei in Python
- Auswirkungen der gemeinsamen Nutzung von Ressourcen durch mehrere Prozesse in Python
- Dateistatus und seine Auswirkungen auf das Sperren einer Datei in Python
- Sperren Sie eine Datei in Python
- Abschluss
Einige Ressourcen können in unserem täglichen Leben nicht von zwei Personen gleichzeitig genutzt werden, zum Beispiel eine Umkleidekabine. Jede Umkleidekabine verfügt über ein Schloss, das jeweils nur von einer Person betreten werden kann.
Wenn zwei Personen gleichzeitig Zugriff hätten, könnte dies zu Verwirrung und Verlegenheit führen. Aus diesem Grund wird die gemeinsam genutzte Ressource mit einer Sperre geschützt.
In ähnlicher Weise können beim Programmieren immer dann, wenn zwei Prozesse oder Threads dieselbe Ressource gemeinsam nutzen, Probleme entstehen, die durch die Verwendung von Sperren vermieden werden müssen. Dieser Artikel erklärt, wie man eine Datei in Python sperrt.
Auswirkungen der gemeinsamen Nutzung von Ressourcen durch mehrere Prozesse in Python
In diesem Abschnitt wird erläutert, warum das Sperren einer Datei in Python wichtig ist.
Das Programm hat zwei Prozesse: Der erste zahlt 1 $ auf ein Konto ein, ein anderer zieht 1 $ davon ab und am Ende wird der Saldo ausgedruckt. Diese Operation wird tausende Male in einer Schleife ausgeführt.
Technisch gesehen würde die Iteration zu keiner Änderung des Endsaldos führen, da die gleiche Zahl immer wieder hinzugefügt und abgezogen wird. Aber wenn das Programm kompiliert wird, sind die Ergebnisse variabel.
import multiprocessing
# Withdrawal function
def wthdrw(bal):
for _ in range(10000):
bal.value = bal.value - 1
# Deposit function
def dpst(bal):
for _ in range(10000):
bal.value = bal.value + 1
def transact():
# initial balance
bal = multiprocessing.Value("i", 100)
# creating processes
proc1 = multiprocessing.Process(target=wthdrw, args=(bal,))
proc2 = multiprocessing.Process(target=dpst, args=(bal,))
# starting processes
proc1.start()
proc2.start()
# waiting for processes to finish
proc1.join()
proc2.join()
# printing final balance
print("Final balance = {}".format(bal.value))
if __name__ == "__main__":
for _ in range(10):
# Performing transaction process
transact()
Ausgang:
C:\python38\python.exe "C:\Users\Win 10\main.py"
Final balance = 428
Final balance = 617
Final balance = -1327
Final balance = 1585
Final balance = -130
Final balance = -338
Final balance = -73
Final balance = -569
Final balance = 256
Final balance = -426
Process finished with exit code 0
Lassen Sie uns den Beispielcode aufschlüsseln, um zu verstehen, warum dies geschieht.
Dieses Programm verwendet das Python-Bibliothekspaket multiprocessing
, um Methoden als Prozesse im Programm aufzurufen.
Die beiden Methoden wthdrw
und dpst
ziehen Geld ab und fügen es dem Konto hinzu. Sie haben einen Parameter, bal
, der für Gleichgewicht steht.
Innerhalb der Methode wird der Wert von bal
in einer for
-Schleife inkrementiert oder dekrementiert. Die Iteration wird 10000 mal wiederholt.
Der bal.value
ist die gemeinsame Ressource in diesem Programm.
# Method to Decrement
def wthdrw(bal):
for _ in range(10000):
bal.value = bal.value - 1
Eine neue Methode transact()
startet die Prozesse übereinander. Innerhalb der Methode wird das Objekt bal
, das den Anfangswert speichert, erstellt und der Saldo auf 100 gesetzt.
def transact():
bal = multiprocessing.Value("i", 100)
lock = multiprocessing.Lock()
Die multiprocessing
-Bibliothek ermöglicht das Starten von Methoden als Prozesse unter Verwendung von Objekten. Beispielsweise wird die Methode wthdrw
gestartet, indem ein Prozess proc1
erstellt wird.
Dieser Prozess zielt auf die Methode wthdrw
und übergibt bal
und ein leeres Objekt als Argumente.
proc1 = multiprocessing.Process(target=wthdrw, args=(bal,))
Ebenso wird ein proc2
-Prozess erstellt, um die dpst
-Methode zu starten. Sind beide Prozesse erstellt, werden sie mit process_name.start()
gestartet.
proc1.start()
proc2.start()
Um einen laufenden Prozess zu schließen, wird die Syntax Prozessname.join()
verwendet. Es stellt die Anforderung hinter einem laufenden Prozess in die Warteschlange, sodass das System wartet, bis der Prozess abgeschlossen ist, und ihn dann schließt.
Der Endsaldo wird nach Abschluss des Vorgangs gedruckt.
print("Final balance = {}".format(bal.value))
Die Variable __name__
wird auf __main
gesetzt und die Methode transact()
innerhalb einer for
-Schleife aufgerufen. Dadurch können wir die Iterationen mehrmals beobachten, ohne Prozesse manuell aufrufen zu müssen.
if __name__ == "__main__":
for _ in range(10):
transact()
Als das Programm ausgeführt wurde, stellten wir fest, dass die Werte inkonsistent waren. Die gemeinsam genutzte Ressource bal.value
ist nicht mit einer Sperre geschützt, sodass der andere Prozess den Wert bearbeitet, bevor der laufende Prozess beendet ist.
Sperren werden verwendet, um dieses Problem zu lösen. Das obige Programm wird gesperrt, indem bei beiden Methoden eine Sperre gesetzt wird; Auf diese Weise muss der Compiler warten, bis der nächste Prozess ausgeführt wird, bevor der vorherige abgeschlossen ist.
# Withdrawal function
def wthdrw(bal, lock):
for _ in range(10000):
# Locks
lock.acquire()
bal.value = bal.value - 1
lock.release()
Die Anweisung lock.acquire()
sperrt den Prozess, und darin wird der Wert von bal
bearbeitet. Danach wird die Sperre mit lock.release()
aufgehoben.
Dasselbe gilt für die dpst
-Methode, und der Rest des Programms bleibt gleich.
Ausgang:
C:\python38\python.exe "C:\Users\Win 10\main.py"
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Final balance = 100
Process finished with exit code 0
Da wir wissen, was mit mehreren Prozessen mit gemeinsam genutzten Ressourcen passiert, werden wir uns eine wichtige Funktion ansehen, die zum Sperren einer Datei in Python erforderlich ist – Dateistatus.
Dateistatus und seine Auswirkungen auf das Sperren einer Datei in Python
Ein Dateistatus zeigt an, ob die Datei geöffnet oder geschlossen ist. Es ist wichtig, den Dateistatus zu kennen, um eine Datei in Python zu sperren, da Sperrvorgänge nur auf geöffnete Dateien angewendet werden können.
Angenommen, es gibt in Python eine Datei – myFile.txt
. Wenn wir schreiben:
readMyFile = open("myFile.txt", "r").read()
Es ist unmöglich, den Status der Datei abzurufen, sie zu schließen oder irgendetwas anderes zu tun. Es gibt keinen Zugriff, weil es nirgendwo gespeichert ist.
Da es keinen Wert hätte, Informationen zu verwerfen und eine Müllsammlung unmöglich wäre, gibt es keine Magie, die es ermöglicht, verloren gegangenes Wissen wiederzugewinnen.
Vermeiden Sie es, Werte zu speichern, die in einer Variablen (einer Liste, einem dict-Mitglied oder einem Attribut einer Instanz) verwendet werden sollen, da dies deren Verwendung ermöglicht.
myFile = open("myFile.txt", "r")
readMyFile = myFile.read()
print(myFile.closed)
myFile.close()
print(myFile.closed)
Der obige Code speichert die Datei in einer Variablen myFile
. Dann verwendet eine andere Variable, readMyFile
, die Variable myFile
, um das Objekt zu lesen.
Mit dieser Methode bleibt die Datei auch nach Abschluss des Lesevorgangs in einem geöffneten Zustand.
Die Syntax print(myFile.closed)
zeigt den aktuellen Dateistatus; hier gibt es einen falschen
Wert zurück, was bedeutet, dass es nicht geschlossen ist. Diese Datei wird explizit mit myFile.close()
geschlossen.
Da das explizite Schließen von Dateien anfällig für menschliche Fehler ist, ist eine bessere Lösung die Verwendung der with
-Anweisung.
with open("myFile.txt", "r") as myFile:
readMyFile = myFile.read()
Jetzt wird myFile
automatisch geschlossen, ohne dass es explizit geschlossen werden muss. Aus dem obigen Beispiel haben wir verstanden, dass effiziente Methoden zum Öffnen und Schließen von Dateien unerlässlich sind, um eine Datei in Python zu sperren.
Eine Datei kann nur in einem geöffneten Zustand gesperrt werden, und eine Datei kann nicht entsperrt werden, wenn keine Sperre vorhanden ist. Das Sperren einer Datei in Python muss immer innerhalb eines with
-Blocks ausgeführt werden.
Sehen wir uns verschiedene Möglichkeiten an, eine Datei in Python zu sperren.
Sperren Sie eine Datei in Python
Dateisperren sind im Allgemeinen Bibliotheken von Drittanbietern, die in Skripten verwendet werden, um eine Datei zu sperren. In diesem Abschnitt werden einige weit verbreitete Dateisperren besprochen.
Sperren Sie eine Datei mit FileLock
in Python
Dies ist eine plattformspezifische Bibliothek zum Sperren von Dateien, die sowohl unter Windows als auch unter UNIX funktioniert. Um es zu installieren, geben Sie den Befehl ein:
pip install filelock
Das Sperren einer Datei mit dieser Methode ist sehr einfach. Öffnen Sie die Datei mit FileLock
innerhalb einer with
-Anweisung, sodass die Datei geöffnet und vom System gesperrt wird.
Nach Abschluss des Vorgangs wird die Sperre am Ende der with
-Anweisung automatisch aufgehoben.
from filelock import FileLock
with FileLock("myfile.txt"):
print("Lock acquired.")
Ausgang:
C:\python38\python.exe "C:/main.py"
Lock acquired.
Process finished with exit code 0
Eine andere Möglichkeit, eine Datei in Python zu sperren, sind Timeouts. Dies hilft, ein Zeitlimit festzulegen, wenn eine Datei nicht gesperrt werden kann, wodurch Dateihandles für andere Prozesse freigegeben werden.
from filelock import FileLock
file = "example.txt"
lockfile = "example.txt.lock"
lock = FileLock(lockfile, timeout=5)
lock.acquire()
with open(file, "a") as f:
print("File Locked")
f.write("Add some data \n")
lock.release()
with open(file, "a") as f:
f.write("Second time writing \n")
Die erste Codezeile importiert das FileLock
-Modul aus der filelock
-Bibliothek. Eine example.txt
-Datei wird in einer variablen Datei gespeichert; diese Datei wird verwendet, um darauf zu schreiben.
Die Sperre wird nicht direkt auf die Originaldatei gesetzt, also wird eine temporäre Datei erstellt, wie example.txt.lock
. Mit der Variable lock
wird ein Lock-Objekt für das lockfile
erzeugt und ein Timeout von 5 Sekunden gesetzt.
Diese Sperre kann mit der Anweisung lock.acquire
gesetzt werden. Ein with
-Block wird verwendet, um die Datei zu öffnen und in sie zu schreiben, während die lockfile
verhindert, dass andere Prozesse auf die Originaldatei zugreifen, während sie geschrieben wird.
Abschliessend wird die Sperre mit lock.release()
aufgehoben. Ein anderer Prozess öffnet dann die Datei und schreibt erfolgreich darauf.
Ausgang:
C:\python38\python.exe "C:/main.py"
File Locked
Process finished with exit code 0
Um eine Datei mit Python zu sperren, können wir die Sperren auch verschachtelt platzieren:
from filelock import Timeout, FileLock
lock = FileLock("high_ground.txt.lock")
with lock:
with open("high_ground.txt", "a") as f:
f.write("You were the chosen one.")
Im obigen Beispiel wird ein lock
-Objekt mit einer Datei namens high_ground.txt
erstellt, um eine Datei in Python zu sperren. Das Schloss befindet sich in einem Block; darin wird die Datei mit einem anderen Block gelesen.
Diese Methode erfordert weniger Code als die vorherige.
Der FileLock
ist plattformabhängig. Wenn jede Anwendungsinstanz auf derselben Plattform läuft, verwenden Sie ein FileLock
; Verwenden Sie andernfalls ein SoftFileLock
.
Ein SoftFileLock
ist plattformunabhängig und überwacht nur die Existenz der Sperrdatei. Aus diesem Grund ist es extrem portabel und friert eher ein, wenn die Anwendung abstürzt.
Löschen Sie in solchen Fällen die Sperrdatei.
File Locker kann auch mit einem Ausnahmebehandlungsblock verwendet werden:
try:
with lock.acquire(timeout=10):
with open(file_path, "a") as f:
f.write("I have a bad feeling about this.")
except Timeout:
print("Another instance of this application currently holds the lock.")
Dieses Code-Snippet platziert eine Sperre innerhalb des try
-Blocks und gibt eine Zeitüberschreitung von 10 Sekunden. Dann wird die Datei in ein verschachteltes with
geschrieben.
Innerhalb des Ausnahme
-Blocks wird eine entsprechende Meldung ausgegeben, wenn die Anwendung das Zeitlimit überschreitet.
Sperren Sie eine Datei mit PortaLocker
in Python
Eine weitere Möglichkeit, eine Datei in Python zu sperren, ist die Verwendung der Bibliothek namens portalocker
, die eine einfache API zum Sperren von Dateien bietet.
Es ist wichtig, sich daran zu erinnern, dass Sperren auf Linux- und Unix-Systemen standardmäßig empfohlen werden. Das obligatorische Sperren von Dateien kann unter Linux aktiviert werden, indem dem Mount-Befehl die Option -o mand
hinzugefügt wird.
Um es zu installieren, geben Sie den Befehl ein:
pip install "portalocker[redis]"
Das Sperren einer Datei in Python mit portalocker
ist ähnlich wie die FileLock
-Methode, aber viel einfacher.
import portalocker
file = "example.txt"
with portalocker.Lock(file, "a") as fh:
fh.write("first instance")
print("waiting for your input")
input()
Ausgang:
C:\python38\python.exe "C:/main.py"
lock acquired
waiting for your input
Im obigen Code importiert die erste Zeile das Bibliothekspaket. Die Sperre wird mit der Syntax portalocker.RedisLock()
erstellt und die Sperre mit einer with
-Anweisung gesetzt.
Um die Sperre innerhalb eines Timeouts zu platzieren, verwenden Sie:
import portalocker
file = "example.txt"
with portalocker.Lock("file", timeout=1) as fh:
print("writing some stuff to my cache...", file=fh)
Ausgang:
Abschluss
Dieser Artikel erklärt, wie man eine Datei in Python sperrt und warum es wichtig ist. Der Leser kann nach dem Lesen dieses Artikels Open-State-Dateien erstellen und sie leicht sperren.
Verwandter Artikel - Python File
- So erhalten Sie alle Dateien eines Verzeichnisses
- Wie man in Python Text an eine Datei anhängt
- Wie man prüft, ob eine Datei in Python existiert
- Wie man Dateien mit einer bestimmten Endung nur in Python findet
- Wie man bestimmte Zeilen aus einer Datei in Python liest
- Dateiberechtigungen in Python ändern