Server handling / Stack

06/09/2015 18:18 Terrat#1
Hallo,
ich wollte gerne etwas für ein Projekt wissen. Normalerweise schreibe ich server derzeit mit dem Konzept each Client = 1 Thread. (boost)
Allerdings würde mich mal interessieren wen mehr als 2000 Threads am laufen sind sind, ist doch der Stack mit 1 GB voll, außer ich reduziere die Stacksize der Threads, was ich jedoch sehr ungerne mache. Wie schreibe ich denn eigentlich so ein Singlethread server ?
1 Thread Accept TCP (Befehle)
1 Thread Accept UDP (Gamedata)

1 Thread Receive Tcp ( alle clients, die der server anhand des sockets einer vorhandenen Klasse zuweist und danach das Packet clientspezifisch abarbeitet )
1 Thread Receive Udp( alle clients )
06/09/2015 19:39 suiluJ.#2
Schau dir mal boost asio an
06/09/2015 21:18 warfley#3
Du solltest vielleicht über das Thread Pool System nachdenken:

[Only registered and activated users can see links. Click Here To Register...]

Quote:
So, most real-world servers use a thread-pool approach, shown to the right. In the thread-pool approach, the main thread creates a fixed number of worker threads. The main thread is still responsible for accepting connections. As it does so, it creates request objects and places them into a data structure such as a linked list or an array. Each worker threads pulls requests out of the buffer according to some scheduling algorithm, and then produces the necessary response. Thus, the main thread can accept connections as long as memory is available, while a fixed number of threads churn away at maximum efficiency.
Quelle: [Only registered and activated users can see links. Click Here To Register...]
06/09/2015 21:31 Padmak#4
Du solltest wie die anderen 2 schon sagten (mehr oder weniger), boost.asio verwenden.
Damit brauchst du bei weitem nicht so viele Threads, da nicht jede Connection ihren eigenen Thread bekommt sondern wie im Bild über mir einem Workerthread was zu tun gibt, das der dann abwickelt. Schau dir am besten die aktuellsten boost.asio-Beispiele an, vor allem im Zusammenhang mit C++11-Lambdas lässt sich damit wunderbar und mit relativ wenigen Zeilen Code performant und sicher arbeiten

Außerdem ist dein größtes Problem bei 2000 Threads sicher nicht der Speicherplatz, der für die Threadstacks draufgeht, sondern die schlichte Anzahl an Daten, die jeder Thread für sich auf dem Heap erzeugt und verwaltet

Padmak
06/09/2015 21:50 Terrat#5
Danke schonmal an alle, aber ich nutze bereits boost asio.
Allerdings lasse ich nach dem der Acceptor das Callback aufgerufen hat ein Thread für eine Client Klasse starten. Aber ich finde derzeit auch nur boost prinzipien mit dem selben beispiel. Hätte mal wer ein Beispiel welches die obrig genante Struktur verwendet ?
06/09/2015 22:11 Padmak#6
Ich empfehle dir, deinen Server so aufzubauen:
[Only registered and activated users can see links. Click Here To Register...]
Die dort benutzte Klasse 'session' entspricht im Großen und Ganzen einem deiner Clients, das ist laut meinem Wissen (ich lasse mich hier gerne korrigieren) eine der effizientesten und praktischten Arten, wie sich so etwas umsetzen lässt.

Die Struktur von oben funktioniert hier leider nicht so 1:1, da du ja die Verbindung offen halten möchtest und nicht für jeden Request eine neue aufmachen willst

Eigentlich sollte aber der Ansatz aus dem Beispiel als Grundidee genau das erreiche, was du haben möchtest.

Padmak
06/10/2015 06:40 Terrat#7
Danke, außer das ich die lamda functions mit callbacks austausche, da ich nicht wirklich gerne solche funktionen nutze.
Aber bei async_read_some, wird da nicht das thread suspendet bis ein packet kommt oder handelt der ioservice das selbst mit 1 thread?
06/10/2015 15:34 Padmak#8
Wie, du nutzt nicht gerne "solche Funktionen"? Solange dein Compiler C++11 mit Lambdas unterstützt, solltest du sie auch verwenden - dein Code wird wesentlich kürzer, klarer und schöner lesbar (und deine Klasse ist nicht voll mit Funktionen, die sich um Verbindungen kümmern)

Nichts wird suspended bis ein Packet kommt, siehe die Referenz dazu: [Only registered and activated users can see links. Click Here To Register...]
Alle async_*-Funktionen returnen immer sofort, darum heißen die ja auch "async" ;)

Padmak
06/10/2015 16:10 Terrat#9
Quote:
Originally Posted by Padmak View Post
Wie, du nutzt nicht gerne "solche Funktionen"? Solange dein Compiler C++11 mit Lambdas unterstützt, solltest du sie auch verwenden - dein Code wird wesentlich kürzer, klarer und schöner lesbar (und deine Klasse ist nicht voll mit Funktionen, die sich um Verbindungen kümmern)

Nichts wird suspended bis ein Packet kommt, siehe die Referenz dazu: [Only registered and activated users can see links. Click Here To Register...]
Alle async_*-Funktionen returnen immer sofort, darum heißen die ja auch "async" ;)

Padmak
Danke hasi !"_! , mag aber trotzdem lieber callbacks @_@ <3 #nohomo
06/10/2015 16:40 Padmak#10
O_o, was auch immer.
Im Endeffekt ist es deine Sache, trotzdem finde ich es komisch wenn du dich gegen Sachen wehrst, die deinen Code besser machen würden
Aber wenn du nicht möchtest, funktionieren wird es so auch

Padmak
06/19/2015 18:26 H-Cheats#11
Just use
public:
Quote:
session(tcp::socket socket)
: socket_(std::move(socket))
06/22/2015 22:35 ლʕಠᴥಠʔლ#12
Ich benutze einfach [Only registered and activated users can see links. Click Here To Register...]
Es ist auch sehr schön dokumentiert.
06/22/2015 23:18 Terrat#13
Bitte schliesen das thema war schon mit Seite 1 abgeschlossen.
06/23/2015 00:46 snow#14
Am besten den Thread immer reporten, dann sehen wir Mods das schneller. :)

#closed