Locks mit Flask & Apache WSGI

Django, Flask, Bottle, WSGI, CGI…
Antworten
dose
User
Beiträge: 3
Registriert: Dienstag 2. Februar 2021, 15:25

Hallo,
Ich nutze Flask über einen Apache Modul WSGI mit Threading=True.
Da die verschiedenen Threads potentiell eine kritische Operation auf einem Objekt gleichzeitig machen können, brauche ich ein Locks.
Wie kann ich mehrere Locks (aufgrund von mehrerer Objekte) in python nutzen?

Beispiel:
Also Thread A erzeugt ein Lock auf Objekt_1
Also Thread B erzeugt ein Lock auf Objekt_2
Also Thread C warten, dass das Lock auf Objekt_1 wieder frei wird, um es dann zu locken und dort seine critical-section abzuarbeiten.

Ich habe über die Suche das Beispiel gefunden:

Code: Alles auswählen

lock = threading.Lock()
with lock:
    # do something
Leider ist mir nicht klar, wie ich sicherstelle, dass mehrere Threads das gleiche Lock "ansprechen" können.
Zudem ist die Anzahl der Objekte für die ein Lock gesetzt werden kann dynamisch.

Kann mir da jemand einen Tip geben?
Herzlichen Dank,
grüße dose
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@dose: Nur mal um sicherzugehen: Du verwendest Windows? Denn unter Linux/Unix ist der Apache normalerweise so übersetzt, dass Anfragen von verschiedenen Prozessen beantwortet werden, das heisst das Threading=True sind dann mehrere Threads pro Prozess. Dann *können* zwei (oder mehr) Anfragen in Threads beantwortet werden die zum gleichen Prozess gehören, es kann aber auch sein, dass die Anfragen in Threads aus verschiedenen Prozessen beantwortet werden.

Eine Webanwendung die darauf angewiesen ist, dass alle Anfragen in *einem* Prozess und von mehreren Threads beantwortet werden, würde ich nicht über Apache und mod_wsgi laufen lassen. Oder ganz ganz deutlich dokumentieren und in der Webanwendung auch am Start prüfen, ob die Randbedingungen auch tatsächlich erfüllt sind. Und es läuft dann alt auch nur mit Apache unter Windows und dem "winnt"-Worker.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

was sind denn das für "kritische Operationen"? Wenn es Datenbankzugriffe sind, dann bringen Datenbanken da den passenden Lock-Mechanismus schon mit.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und wenn keine DB, dann wäre es ggf von Vorteil, einen Service zu schreiben, den die flask worker benutzen.
dose
User
Beiträge: 3
Registriert: Dienstag 2. Februar 2021, 15:25

Hallo @_blackjack_,
Vielen Dank für die Antwort.
Nein, ich verwende Linux mit Apache. Danke für den Hinweis mit den Prozessen und den Threads.
Mein Gedanke ist, ob ich nicht mit Lock-Files arbeiten kann, da müsste es ja dann egal sein, welcher Thread (von welchem Prozess) ein Lock anfragt oder frei gibt.
z.B. https://pypi.org/project/filelock/ oder https://docs.python.org/3/library/fcntl.html
Kann das funktionieren? Gibt es evtl. sogar einen eleganteren Weg?

@Sirius3:
Die kritischen Operationen beziehen sich auf ein externes Interface (ohne Lock support), d.h. es gibt keine Datenbank die ggf. ein Locking mitbringt.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Dann solltest du dem Ratschlag von deets folgen.
dose
User
Beiträge: 3
Registriert: Dienstag 2. Februar 2021, 15:25

@__deets__: Was genau meinst du mit Service?
Einen eigenen Daemon der nur das Locking handlet? Aber selbst dann habe ich das Problem ja nur verlagert und die Frage stellt sich weiterhin, wie ich das eigentliche Problem realisiere...
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Unter Linux ist das eigentlich ganz einfach mit Semaphoren: https://pypi.org/project/posix-ipc/
Antworten