Serverprogrammierung - Theorie?
-
Asynchrone Verarbeitung und Threads sind keine orthogonalen Konzepte. Man kann auch beides haben.
-
TyRoXx schrieb:
tntnet schrieb:
Was accept oder recv macht, wenn man den Socket schließt, ist meines Wissens nicht spezifiziert. Besser ist es, tatsächlich mit non-blocking zu arbeiten und erst dann accept bzw. recv aufzurufen, wenn auch tatsächlich jemand anklopft.
Da kann man auch gleich
selectnehmen. Oder funktioniert das ganz anders?Das ist doch genau das, worauf ich hinaus wollte. Hätte ich vielleicht direkt darauf hinweisen sollen. Also Socket auf non-blocking und dann mit
selectwarten, bis jemand anklopft. Und imselectkann man dann noch eine pipe rein packen, womit ich den select geordnet wecken kann, wenn ich den Server runter fahren möchte.cooky451 schrieb:
tntnet schrieb:
Performancemässig hängt es von der Applikation ab.
Nö. Asynchrone Modelle dürften immer schneller sein. Nur merkt man das eben erst ab einer ordentlichen Menge Clienten.
Das stimmt so nicht. Wenn die Verarbeitung einer Antwort signifikant lange dauert, dann ist das besser, wenn er in einem separaten Thread verarbeitet wird. Ein rein asynchroner Thread läuft auf genau einem Core und wenn ein Request bearbeitet wird, müssen die anderen warten.
Nehmen wir ein einfaches Rechenmodell: Ein Request kommt an und der Server braucht eine Sekunde, um die Antwort zu generieren. Während er die Antwort generiert, kann er im asynchronen Modell keine weiteren Requests verarbeiten. Er schafft also genau einen Request pro Sekunde. Wird der Request in einem Thread generiert, kann ein anderer Thread bereits den nächsten Request entgegennehmen und verarbeiten. Habe ich dann beispielsweise 8 Cores, kann der multithreaded Server halt 8 Requests pro Sekunde verarbeiten.
-
Man kann immer noch (meine Posts liest ja offenbar niemand) asynchrone IO mit beliebig vielen Threads verwenden. Dein Beispiel ist daher totaler Schwachsinn.
-
tntnet schrieb:
Also Socket auf non-blocking und dann mit
selectwarten, bis jemand anklopft.Genau, erst non-blocking machen, und dann zur Sicherheit noch mal select fragen, das ist ein Plan.

@threads Das hat dann aber nichts mehr mit I/O Performance zu tun.
-
Ich kapere den thread kurz mal für eine kleine Frage:
Ich würde gerne einen minichat clienten basteln. Da ich die select variante doof finde, wrde ich gerne threads verwenden.
Würde zwei threads, je einen für recv und send(main aktualisiert nur das chatfenster), verwenden.
Kann ich den erstellten socket an die threads übergeben ohne das Fehler passieren? Laut dem was ich gelesen habe funktioniert direkte Übergabe per Referenz nicht, da sich durch die threads(gebe nur wieder was ich gelesen habe), die Speicheradresse(der socketvariable) ändert(oder ändern kann).
-
Adressen von Variablen ändern sich grundsätzlich niemals, allerdings kann die Variable im anderen Thread zerstört werden, während du noch eine Referenz auf sie hast.
Übergib einfach by value und gut ist.
-
314159265358979 schrieb:
Asynchrone Verarbeitung und Threads sind keine orthogonalen Konzepte. Man kann auch beides haben.
Weil orthogonale Konzepte bildlich auf zwei Dimension liegen, x- und y-Achse, kannst man sie unabhänig von einander steuern. Deine Nutzung macht mir allerdings Kopfschmerzen.

-
Athar schrieb:
Adressen von Variablen ändern sich grundsätzlich niemals, allerdings kann die Variable im anderen Thread zerstört werden, während du noch eine Referenz auf sie hast.
Übergib einfach by value und gut ist.Geht leider bei C Posix nicht(ich weiß hier ist es c++, dachte läuft ähnlich. Zumal ich dachte, dass das dann nicht funktioniert).
Hier das Beispiel das ich meinte:
" This example performs argument passing incorrectly. It passes the address of variable t, which is shared memory space and visible to all threads. As the loop iterates, the value of this memory location changes, possibly before the created threads can access it. "
https://computing.llnl.gov/tutorials/pthreads/#PassingArguments
Beispiel 3.Wieso solte sich der Wert des Speicherorts ändern oO
-
Namenloser324 schrieb:
Athar schrieb:
Adressen von Variablen ändern sich grundsätzlich niemals, allerdings kann die Variable im anderen Thread zerstört werden, während du noch eine Referenz auf sie hast.
Übergib einfach by value und gut ist.Geht leider bei C Posix nicht(ich weiß hier ist es c++, dachte läuft ähnlich. Zumal ich dachte, dass das dann nicht funktioniert).
Hier das Beispiel das ich meinte:
" This example performs argument passing incorrectly. It passes the address of variable t, which is shared memory space and visible to all threads. As the loop iterates, the value of this memory location changes, possibly before the created threads can access it. "
https://computing.llnl.gov/tutorials/pthreads/#PassingArguments
Beispiel 3.Wieso solte sich der Wert des Speicherorts ändern oO
ACH, lol, die meinen der Wert der an dieser Adresse steht, oder?
-
Jo.
-
cooky451 schrieb:
Jo.
hachja, was man manchmal rausliest...

vielen dank
-
Zeus schrieb:
Weil orthogonale Konzepte bildlich auf zwei Dimension liegen, x- und y-Achse, kannst man sie unabhänig von einander steuern. Deine Nutzung macht mir allerdings Kopfschmerzen.

Ich behaupte mal, dass es absolut gängig ist bei asynchroner IO, dass die Handler von mehreren, verschiedenen Threads aufgerufen werden. Was stört dich daran?
-
314159265358979 schrieb:
Asynchrone Verarbeitung und Threads sind keine orthogonalen Konzepte. Man kann auch beides haben.
Du hast nicht verstanden was "orthogonal" in diesem Zusammenhang bedeutet.
Natürlich sind asynchrone Verarbeitung und Threads orthogonale Konzepte.
Ich kann mich auf der "asynchrone Verarbeitung" Achse bewegen ohne die "Threads" Achse zu beeinflussen, und ich kann mich auf der "Threads" Achse bewegen ohne die "asynchrone Verarbeitung" Achse zu beeinflussen.D.h. asynchrone Verarbeitung und Threads sind unabhängig voneinander, genau so wie die X und Y Achsen in einem Bild unabhängig voneinander sind.
Und das nennt man orthogonal.
Und genau so wie man mit gleichzeitiger Verwendung von X und Y schöne Bilder malen kann, kann man auch mit gleichzeitiger Verwendung von asynchroner Verarbeitung und Threads schöne Programme schreiben.
-
cooky451 schrieb:
tntnet schrieb:
Also Socket auf non-blocking und dann mit
selectwarten, bis jemand anklopft.Genau, erst non-blocking machen, und dann zur Sicherheit noch mal select fragen, das ist ein Plan.

Natürlich ist das ein Plan. Wie willst du es denn mit non-blocking IO ohne alternativem IO-Demultiplexer sonst machen? Busy-Loop auf recv() so lange bis was angekommen ist?
Nebenbei ist das auch ein Plan, den viele Server-Programme erfolgreich umgesetzt haben. Man muss nicht immer mit Kanonen auf Spatzen schiessen.
Non-blocking + select() hat schon ein paar Nachteile, aber es hat den Vorteil ziemlich einfach zu sein.
-
hustbaer schrieb:
Natürlich ist das ein Plan.
Es ging um Threads/Client + select damit man die Anwendung ordentlich beenden kann. Wozu jetzt noch non-blocking Sockets? select() garantiert ja schon, dass man etwas empfangen kann. Die Zeit, die recv() dann noch braucht ist für's Beenden wohl eher uninteressant. Was du beschreibst, klingt eher nach http://www.c-plusplus.net/forum/299892
-
Blocking Sockets und select (oder ähnliche Funktionen) sind problematisch, spätestens wenn du send benutzt. Denn sagt dir select wieviel Bytes man senden kann? Nein.
Und es sind auch viele Fälle von "spurious wakeup" bekannt, wo select fälschlicherweiße was meldet. Oder sich die Situation zwischen select und dem recv/send/accept ändert.
-
Namenloser324 schrieb:
Ich kapere den thread kurz mal für eine kleine Frage:
Ich würde gerne einen minichat clienten basteln. Da ich die select variante doof finde, wrde ich gerne threads verwenden.
Würde zwei threads, je einen für recv und send(main aktualisiert nur das chatfenster), verwenden.
Kann ich den erstellten socket an die threads übergeben ohne das Fehler passieren? Laut dem was ich gelesen habe funktioniert direkte Übergabe per Referenz nicht, da sich durch die threads(gebe nur wieder was ich gelesen habe), die Speicheradresse(der socketvariable) ändert(oder ändern kann).Dir fehlen also wesentliche Grundlagen der Programmierung. Aber du weißt ganz genau, dass es unbedingt Threads sein müssen.
selectist ja schließlich doof.
-
cooky451 schrieb:
hustbaer schrieb:
Natürlich ist das ein Plan.
Es ging um Threads/Client + select damit man die Anwendung ordentlich beenden kann. Wozu jetzt noch non-blocking Sockets? select() garantiert ja schon (...)
select() garantiert gar nix, siehe Antwort von bs_.
Blocking IO + select() = bug ticket waiting to be written