hi,
ich stehe vor dem problem das MySQL (das protkoll) nur eine aktion je connection gleichzeitig ausführen kann (was mich auch eigentlich garnicht stört). ich benutze in meinem programm 10 worker threads die manchmal eine mysql aktion ausführen müssen. als eigene lösung dachte ich mir das ich einfach eine Queue.Queue benutze und einen extra thread der diese Queue permanent abfrägt. das problem wäre dann aber wenn ich werte aus einer mysql tabelle lesen möchte eben mit dieser methode blöd darstehen würde.
hat jemand vielleicht eine bessere idee? ich dachte auch schon evtl an das locken der threads, was ich aber nur ungern machen möchte.
PS: ich verwende für die verbindung MySQLdb
mit freundlichen grüßen
- Volvic
MySQL threadsafe verwenden?
Ich hab' dir mal einen möglichen Ansatz skizziert. Du bräuchtest nur noch einen Datenbank-Thread, welcher die Anfragen in einer Queue entgegen nimmt und diese nacheinander mit "commit" abarbeitet.
In "SQLStatement" kannst du anfragen stecken, die eine Änderung durchführen, in "SQLExpression" eine Anfrage, die ein Ergebnis liefert. Dieses wird dann in "result" abgelegt.
Nach Abarbeitung einer Anfrage wird "done" gesetzt um der anfragend Thread mitzuteilen, dass die Anfrage abgearbeitet ist.
Das "_before" habe ich einfach mal aus Gründen der Symmetrie eingefügt, vielleicht braucht man es ja bei Gelegenheit noch mal.
In "SQLStatement" kannst du anfragen stecken, die eine Änderung durchführen, in "SQLExpression" eine Anfrage, die ein Ergebnis liefert. Dieses wird dann in "result" abgelegt.
Nach Abarbeitung einer Anfrage wird "done" gesetzt um der anfragend Thread mitzuteilen, dass die Anfrage abgearbeitet ist.
Das "_before" habe ich einfach mal aus Gründen der Symmetrie eingefügt, vielleicht braucht man es ja bei Gelegenheit noch mal.
Code: Alles auswählen
import threading
class SQLRequest(object):
def __init__(self, sql):
self.sql = sql
self.done = threading.Event()
def commit(self, dbcursor, dbparams):
self._before(dbcursor, dbparams)
dbcursor.execute(self.sql, dbparams)
self._after(dbcursor)
self.done.set()
def _before(self, dbcursor, dbparams):
pass
def _after(self, dbcursor):
pass
class SQLStatement(SQLRequest):
def _after(self, dbcursor):
dbcursor.commit()
class SQLExpression(SQLRequest):
def _after(self, dbcursor):
self.result = dbcursor.fetchall()
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Volvic!Volvic hat geschrieben:ich benutze in meinem programm 10 worker threads die manchmal eine mysql aktion ausführen müssen.
CherryPy gibt dir die Möglichkeit, eine Connection an einen Thread zu binden. Damit kannst du eine Verbindung zum MySQL-Server **je** Thread aufmachen. Somit hast du dann 10 Threads und 10 Verbindungen offen. -- ideal!
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import cherrypy
# Ganz egal wo im Programm du bist. "cherrypy.thread_data" enthält immer nur
# die **im aktuellen Thread** zugewiesenen Daten. Das wird im Hintergrund
# durch die Verwendung von "threading.local" erreicht. Dieser Platz ist dadurch
# ideal dafür geeignet, eine Connection zu einer MySQL-Datenbank aufzunehmen.
thread_data = cherrypy.thread_data
# Wenn es die Verbindung noch nicht gibt, dann Verbindung initialisieren...
if not hasattr(thread_data, "conn"):
thread_data.conn = "Irgendeine Datenbankverbindung"
# Verbindung verwenden...
print thread_data.conn
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
...Hier noch ein kleiner Nachtrag:
Da steht alles drinn, was man so brauchen könnte und wie man die Sache am Schönsten angehen kann.
http://tools.cherrypy.org/wiki/Databases
mfg
Gerold

Da steht alles drinn, was man so brauchen könnte und wie man die Sache am Schönsten angehen kann.
http://tools.cherrypy.org/wiki/Databases
mfg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- Damaskus
- Administrator
- Beiträge: 999
- Registriert: Sonntag 6. März 2005, 20:08
- Wohnort: Schwabenländle
Moin,Code: Alles auswählen
#!/usr/bin/env python # -*- coding: iso-8859-15 -*- import cherrypy # Ganz egal wo im Programm du bist. "cherrypy.thread_data" enthält immer nur # die **im aktuellen Thread** zugewiesenen Daten. Das wird im Hintergrund # durch die Verwendung von "threading.local" erreicht. Dieser Platz ist dadurch # ideal dafür geeignet, eine Connection zu einer MySQL-Datenbank aufzunehmen. thread_data = cherrypy.thread_data # Wenn es die Verbindung noch nicht gibt, dann Verbindung initialisieren... if not hasattr(thread_data, "conn"): thread_data.conn = "Irgendeine Datenbankverbindung" # Verbindung verwenden... print thread_data.conn
eine Frage hab ich noch dazu.
Wie kann ich die 10 offenen Verbindungen die cherrypy beim start erstellt dann wieder schließen. Bzw. worum es mir geht ist eher wie kann ich bei einem Shutdown des cherrypy Servers die ganzen offenen Verbindungen schließen?
Denn cherrypy kennt keine möglich eine bestimmte Funktion vor dem shutdown auszuführen.
Oder irre ich mich da?
Danke.
Mfg
Damaskus
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Damaskus!Damaskus hat geschrieben:worum es mir geht ist eher wie kann ich bei einem Shutdown des cherrypy Servers die ganzen offenen Verbindungen schließen?
Ich denke mal, dass die Connections beim Zerstören von *thread_data* automatisch geschlossen werden. -- Gleich wie beim File-Objekt. Dieses wird ja auch geschlossen, auch wenn man *close()* nicht explizit vor dem Ende eines Programmes aufruft.
Hattest du Probleme die darauf hinweisen, dass die Connections nicht geschlossen werden?
lg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- Damaskus
- Administrator
- Beiträge: 999
- Registriert: Sonntag 6. März 2005, 20:08
- Wohnort: Schwabenländle
Hallo Gerold,gerold hat geschrieben:Hallo Damaskus!Damaskus hat geschrieben:worum es mir geht ist eher wie kann ich bei einem Shutdown des cherrypy Servers die ganzen offenen Verbindungen schließen?
Ich denke mal, dass die Connections beim Zerstören von *thread_data* automatisch geschlossen werden. -- Gleich wie beim File-Objekt. Dieses wird ja auch geschlossen, auch wenn man *close()* nicht explizit vor dem Ende eines Programmes aufruft.
Hattest du Probleme die darauf hinweisen, dass die Connections nicht geschlossen werden?
lg
Gerold
es war eher nur ein Gedankengang von mir.
Ich hab das heute mal getestet und es ist so wie du vermutet hast das die Connections mit dem zerstören von "thread_data" geschlossen werden.
Allerdings ergibt sich jetzt ein neues Problem. Die Connections die offen sind, bleiben bei MySQL dauerhaft im "sleep" Status was mir wiederum nicht gefällt.
Aber dazu bastel ich mir noch eine Kontroll/Steuerungsfunktion.
Gruß
Damaskus