non-blocking-sockets: select unterbrechen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Ich verwende non-blocking threads und weiss nicht genau wie ich folgendes Lösen soll:

select wartet gerade, bis an den sockets etwas passiert, in diesem Moment möchte ich Daten über den Socket schicken.

- Wenn ich den Socket in die SchreibListe des selects schmeisse, ist die CPU-Last hoch, weil der socket immer schreibbar ist und select somit immer gleich weiter springt.

- Wenn ich aber den socket nur in die Liste tue wenn auch Daten anliegen, kann es passieren dass select wartet und den socket noch nicht in der Liste hat. Dieser wird erst beim nächsten Schleifendurchgang hinzugefügt. Somit könnte der Datenversand ziemlich verzögert sein.

Ich hatte nun schon die Lösung dass ich einfach einen socket habe der auf localhost horcht und wenn ich nun Daten habe kann ich select unterbrechen indem ich zu dem socket verbinde. Jedoch finde ich das irgendwie eine Bastellösung.

Ich könnte auch gar nicht auf schreibbar warten sondern direkt socket.send benutzen, jedoch weiss ich nicht ob das so richtig ist.

Wie könnte ich das sonst noch Lösen?

Ach ja für die, die es interessiert: Ich hab mir sozusagen ein asyncore gemacht, nur mit weniger Magic, irgendwie gefällt mir eine globale Map nicht.

Gruss
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Überprüfe nur ob ein socket schreibbar ist wenn du auch etwas zu schreiben hast ;)
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Ok aber wenn select nun am warten ist und gar nicht mitbekommt, dass ein neuer socket auf schreibbar überprüft werden muss?

Gruss
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Dafür hast du den Timeout. Nach dem generierst du die Liste wieder neu ;)
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Ok dann kann es einfach eine feste Verzögern (länge vom Timeout) geben.

Gruss
Gromit
User
Beiträge: 51
Registriert: Montag 8. Mai 2006, 19:07

rayo hat geschrieben:Ok dann kann es einfach eine feste Verzögern (länge vom Timeout) geben.
Das kann eigentlich nur passieren, wenn ein Socket durch einen
anderen Thread in den Zustand "ich kann senden" versetzt wird.

Unter Windows kommt man aus dem Problem wieder raus, indem man
WaitForMultipleObject verwendet und auf Events wartet, welche man mit
dem Socket verbindet; die API-Funktion, die das macht, hab ich vergessen.

Unter Linux kann sich damit behelfen, das man dem select noch einen
zusätzlichen unix-socket oder eine pipe übergibt, in die der Thread, welcher
die zu versendenden Daten erzeugt, etwas reinschreibt. So kehrt das
select auch in diesem FAll zurück.

HTH,
Gerald
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Gromit, wieso den Umweg über die Pipe gehen wenn es auch mit einem Timeout geht?
Gromit
User
Beiträge: 51
Registriert: Montag 8. Mai 2006, 19:07

veers hat geschrieben:Gromit, wieso den Umweg über die Pipe gehen wenn es auch mit einem Timeout geht?
Weils dann sofort reagiert.
Reagiert man nicht sofort, kann das bei RPC-artigen Protokollen zu einem sehr niedrigen Durchsatz führen.
Setzt man den timeout nahe 0, so hat man zwar einen guten Durchsatz, aber auch sehr schnell 100% CPU-Last, d.h. für die eigentliche Informationsverarbeitung bleibt dann nichts mehr.
Man beachte, daß unter Linux der select sofort zurückkehrt, wenn der timeout kleiner als die Zeitscheibe ist.
Antworten