Asynchat + "Timer"

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Moin!

Das Programm, welches ich gerade schreibe, nutzt asynchat, um mit einem Server zu kommunizieren. Das klappt auch sehr gut, asynchat laesst sich ja sehr komfortabel nutzen. Das Problem: Das Programm soll zusaetzlich (unabhaenging von Server-Events) alle n Sekunden etwas tun und daraufhin evtl. etwas an den Server raussenden.

Mein erster Gedanke war, einen zweiten Thread fuer den "Timer" aufzumachen, der dann auf meinem asynchat-Objekt die push-Methode aufruft. Das Asynchat-Modul ist aber nicht threadsafe, mein erster schneller Versuch, es mit diversen Locks zum Schreiben threadsafe zu machen, hat erstmal nicht geklappt. Bevor ich mir die Muehe mache und den Ansatz weiterverfolge, wuerde ich gerne erstmal Alternativen ueberdenken.

Eine andere Moeglichkeit waere ja, etwas zu bauen, was man in die Event-Loop von asynchat integrieren koennte. Etwas, was auf diesen select-Kram alle n Sekunden mit ok reagiert. Am einfachsten umzusetztende Variante: Ein "Timer"-Thread, der nen eigenen Socket auf dem Loopback-Device aufmacht, wo man dann ein eigenes asynchat-Objekt drauf horchen laesst, welches dann das push auf dem Server-asynchat-Objekt aufruft. Momentan scheint mir das die elegantere Loesung zu sein.

Gibt's noch mehr Moeglichkeiten? Andere Module? Twisted? Mal davon abgesehen, dass ich Twisted kaum kenne, scheint mir das auch ein wenig Overhead zu sein.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Die `readable`- bzw. `writable`-Methode des asyn_chat-Objekts müsste eigentlich mindestens alle `n` Sekunden aufgerufen werden, wobei `n` hier der Wert ist, den man `asyncore.loop` als `timeout`-Parameter übergibt. Vielleicht könnte man darüber ja etwas machen.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Warum ist das nicht threadsafe? Der Fifo der gebraucht wird für den Outputbuffer verwendet deque, das Threadsafe ist. Gibt es denn Probleme? Bei Producer/Consumer gibts ja nicht all zu viele Probleme.

Also die Lösung mit einem Socket finde ich unschön.

Gruss
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

rayo hat geschrieben:Warum ist das nicht threadsafe? Der Fifo der gebraucht wird für den Outputbuffer verwendet deque, das Threadsafe ist. Gibt es denn Probleme?
`push` ruft `initiate_send` auf, und `initiate_send` ist nicht thread-safe.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Trundle: Werde ich mir heute abend mal anschauen, danke fuer den Tipp!

rayo, auf die Sache mit dem deque bin ich auch erst reingefallen. Aber wie trundle sagte, es gibt noch an anderen Stellen Probleme, und ja, die kann ich bei mir auch feststellen. :cry:
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Dann würde ich ein push schreiben ohne das initiate_send und den timeout beim loop auf 0.1s stellen.

Dann gibts einfach die Möglichkeit, dass die Daten 100ms später versendet werden, kommt aber in den meisten Fällen nicht auf diese Zeit an.

Gruss
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Ich hab's jetzt erstmal so geloest, dass mein Thread nicht mehr direkt seine Nachrichten rausschreibt, sondern erstmal in eine Queue. Von dort holt sich die writable-Methode von dem asynchat-Objekt die Nachrichten und pusht sie dann raus. Wenn man den Timeout der asyncore.loop klein genug waehlt, funktioniert das fuer meine Zwecke hervorragend, und die merkwuerdigen Probleme, die ich auf das Threading geschoben habe, sind seither nicht mehr aufgetreten. :)

Ich muss nochmal schauen, wie rechenintensiv mein zusaetzlicher Thread eigentlich ist, denn vielleicht kann ich auch komplett auf ihn verzichten und die writeable-Methode die Funktionen direkt aufrufen lassen.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Antworten