Ist ein Django-Session-Thread sicher?

8

Ich speichere ein Wörterbuch in einer Django-Sitzung, auf die mehrere Threads zugreifen können. Alle Threads können dieses Wörterbuch aktualisieren, Threads erhalten auch Werte aus dem Dictionary, um den Prozess auszuführen. Ich möchte wissen, ob die Django-Sitzung threadsicher ist oder ich Sperren oder Semaphore verwenden muss?

Typisches Beispiel:

%Vor%

Besteht die Möglichkeit, dass wenn Point2 das Thread-Wörterbuch in der Sitzung aktualisiert, unmittelbar nachdem es Point1 aktualisiert, es auch aktualisiert, dann ist mein stop zum Beenden des Threads verloren.

Weitere Informationen

Eine Ajax-Anfrage startet vier Threads, die Samples von den vier verschiedenen URLs herunterladen. Warum habe ich Threads verwendet? weil ich dem Benutzer zeigen möchte, welche Samples gerade heruntergeladen werden und welche übrig sind. Alle Threads aktualisieren ihren Status im Wörterbuch innerhalb der Sitzung. Nachdem Threads gestartet wurden, mache ich alle zwei Sekunden eine Ajax-Anfrage und nehme das Wörterbuch aus der Sitzung und lese den aktuellen Status der Threads. Diese Idee ist jedoch fehlgeschlagen, da Threads unabhängig von der Anfrage und ihrer Sitzung sind. Jede Ajax - Anfrage hat definitiv ihre Sitzung, aber ich kann diese Sitzung nicht an Threads weitergeben, da sie, wenn sie einmal begonnen haben, unabhängig vom Rest der Welt sind (vielleicht kann ich sie passieren, aber ich kann sie nicht so schnell passieren wie die Threads). Um dieses Problem anzugehen, wähle ich Cache Framework statt Session. als Cache ist von jedem wo zugänglich. Threads speichern ihren Status im Dictionary und legen ihn wieder in den Cache. Nach jeweils zwei Sekunden nehme ich das Dictionary aus dem Cache und lese den Status. Und noch eine Sache nach meiner Erfahrung Cache ist nicht threadsicher. Also für vier Threads habe ich vier Wörterbücher getrennt verwendet.

    
Aamir Adnan 21.11.2011, 12:47
quelle

5 Antworten

6

Das zurückgegebene request.session -Objekt wird für jede Anfrage neu und greift auf denselben Speicher zu. Außerdem werden sie zum Zeitpunkt der Anforderung aus dem Speicher geladen und zur Reaktionszeit zurückgespeichert. Wenn Sie also Informationen aus einem lang laufenden Thread in eine andere Anfrage übertragen möchten, müssen Sie sie manuell im lang laufenden Thread speichern. Leider führt dies dazu, dass Änderungen an den Daten derselben Sitzung verloren gehen.

Die Sitzung ist in gewissem Sinne Thread-sicher. Sie werden den Interpreter auf diese Weise nicht brechen. Ihre Anfrage wird die Sitzungsdaten als eine Momentaufnahme davon beim ersten Zugriff sehen, und beim Speichern werden alle Änderungen überschrieben, die seit diesem Moment gelandet sind. Der Sitzungsstatus wird also konsistent sein, aber die Änderungen einiger Anfragen können verloren gehen.

Tatsächlich ist diese Eigenschaft für praktisch jedes Framework üblich - jede Sitzung / jedes Caches / irgendein anderer Speicher, der zwischen mehreren Prozessen geteilt werden kann, ist sehr unwahrscheinlich, Änderungen der darin gespeicherten Objekte bereitzustellen, ohne dass die Änderungen von jemandem überschrieben werden. p>     

Tanriol 18.12.2011, 11:54
quelle
2

Django-Sitzung ist ein Wörterbuch, das zu Beginn der Anforderungsverarbeitung abgerufen und am Ende wieder gespeichert wird [ Quelle ]. Wenn Sie also parallele Änderungen daran vornehmen, wird eine dieser Änderungen vorherrschen. Aber typischerweise kann ein menschlicher Benutzer solche parallelen Aktionen nicht durchführen und das Geschäft geht einfach weiter.

Nun, ich verstehe Ihr Beispiel nicht ganz, aber es sieht so aus, als würden Sie einfach das Sitzungswörterbuch missbrauchen. Ich habe eine ganze Reihe von Django-basierten Websites entwickelt, ich habe mich auf eine Reihe von Problemen im Zusammenhang mit den Einschränkungen oder Bugs in Django selbst konzentriert, aber das Durcheinander mit dem Session-Dict aus mehreren Threads sieht für mich wie ein Lehrbuchbeispiel aus Missbrauch der Sitzung ..

Vielleicht könnten wir die Lösung herausfinden, wenn Sie etwas mehr über das, was Sie erreichen wollen, schreiben?

    
Tomasz Zielinski 19.12.2011 02:34
quelle
0

Die Grundtypen in Python sind generell threadsicher dank der globalen Interpretersperre . Diese Sperre wird in einigen Situationen (z. B. beim Ausführen von E / A) aufgehoben, um anderen Threads den Zugriff zu ermöglichen. Dies bedeutet, dass Sie (die Anwendung) einen konsistenten Zustand über alle Anrufe aufrechterhalten müssen, die die GIL freigeben könnten. Ein Beispiel für solche Methoden sind Socket-Operationen blockieren.

    
Krumelur 21.11.2011 13:27
quelle
0

Ich bin mir nicht sicher, ob Django threadsicher ist. Zum Beispiel ist django / core / urlresolvers.py nicht Thread-sicher, wenn Sie Apache + mod_wsgi config mit mehreren Threads pro Prozess verwenden. aber sie arbeiten, um es zu tun. Einige Tickets sind auf dem Django Ticketing-System 15849

    
francois 29.11.2011 22:49
quelle
0

Wie von @Krumelur erwähnt, werden Python-Threads wegen der globalen Interpeter-Sperre (GIL) nicht gleichzeitig ausgeführt - es ist ein Mangel, kein Feature, also verlassen Sie sich nicht darauf.

Die aktuelle Problemumgehung besteht darin, einen Unterprozess mit dem Multiprocessing-Modul zu erstellen. Mit der Funktion is_alive () der Process-Instanz können Sie überprüfen, ob ein Subprozess ausgeführt wird. Weitere Informationen finden Sie in den Dokumenten für die saftigen Details .

    
Lester Cheung 23.12.2011 06:59
quelle