Proactor und geteilter Zustand
Verfasst: 04.06.2012, 22:47
Moin,
ich bin grade bei den ersten Entwufsschritten zu einem Server für mein Projekt (das man am ehesten mit RTS beschreiben kann). Da ich mich gerne vom "klassischen" Multithreading mit synchronem I/O trennen möchte, grübele ich seit einer Weile über das Proactor-Pattern, insbesondere in Form von boost::asio nach.
Wo ich momentan etwas am Zaudern bin, ist die Frage nach dem Umgang mit dem globalen Zustand des Spiels. Ich schwanke zwischen zwei Varianten:
1. Komplette Netzwerkkommunikation asynchron, aber in den Completion Handlern synchrone Operationen (mit allen Vor- und Nachteilen) auf den Spielzustand ausführen.
2. Alles asynchron, nur in einem Thread Veränderungen des Spielzustands erlauben und ihm von den anderen Threads aus Befehle in Form von Nachrichten schicken.
Für beide Varianten fallen mit gute Argumente und Gegenargumente ein:
Variante 1 erlaubt den gleichzeitigen Zugriff auf alle Spielobjekte von den Completion Handlern aus, außerdem könnte ein weiterer Thread zeitabhängige Änderungen vornehmen. Der Nachteil ist, dass unter Umständen (i.e. garantiert) die Completion Handler bei der Synchronisation blockieren und somit einen oder mehrere (der wenigen) für das Abarbeiten der Events zuständigen Threads verschwenden.
Variante 2 löst diese Probleme und kann über einfache Timer-Events auch zeitabhängige Änderungen vornehmen. Eine weitere Synchronisation zwischen den Threads ist nicht mehr nötig. Der Nachteil ist, dass für alle Operationen auf dem Spielzustand nur ein Thread zuständig ist, und das, obwohl diese Operationen einen Großteil der Arbeit des Servers ausmachen werden, außerdem ergibt sich zwangsläufig ein gewisser Overhead für das Messagepassing.
Ich tendiere momentan zu der "saubereren" Lösung 2, eventuell unter Aufteilung verschiedener Bereiche des Spielzustands auf verschiedene Threads.
Hat sich von euch schonmal wer mit dieser Frage beschäftigt? Zu welchen Erkenntnissen seid ihr gelangt? Übersehe ich eine bessere Möglichkeit?
ich bin grade bei den ersten Entwufsschritten zu einem Server für mein Projekt (das man am ehesten mit RTS beschreiben kann). Da ich mich gerne vom "klassischen" Multithreading mit synchronem I/O trennen möchte, grübele ich seit einer Weile über das Proactor-Pattern, insbesondere in Form von boost::asio nach.
Wo ich momentan etwas am Zaudern bin, ist die Frage nach dem Umgang mit dem globalen Zustand des Spiels. Ich schwanke zwischen zwei Varianten:
1. Komplette Netzwerkkommunikation asynchron, aber in den Completion Handlern synchrone Operationen (mit allen Vor- und Nachteilen) auf den Spielzustand ausführen.
2. Alles asynchron, nur in einem Thread Veränderungen des Spielzustands erlauben und ihm von den anderen Threads aus Befehle in Form von Nachrichten schicken.
Für beide Varianten fallen mit gute Argumente und Gegenargumente ein:
Variante 1 erlaubt den gleichzeitigen Zugriff auf alle Spielobjekte von den Completion Handlern aus, außerdem könnte ein weiterer Thread zeitabhängige Änderungen vornehmen. Der Nachteil ist, dass unter Umständen (i.e. garantiert) die Completion Handler bei der Synchronisation blockieren und somit einen oder mehrere (der wenigen) für das Abarbeiten der Events zuständigen Threads verschwenden.
Variante 2 löst diese Probleme und kann über einfache Timer-Events auch zeitabhängige Änderungen vornehmen. Eine weitere Synchronisation zwischen den Threads ist nicht mehr nötig. Der Nachteil ist, dass für alle Operationen auf dem Spielzustand nur ein Thread zuständig ist, und das, obwohl diese Operationen einen Großteil der Arbeit des Servers ausmachen werden, außerdem ergibt sich zwangsläufig ein gewisser Overhead für das Messagepassing.
Ich tendiere momentan zu der "saubereren" Lösung 2, eventuell unter Aufteilung verschiedener Bereiche des Spielzustands auf verschiedene Threads.
Hat sich von euch schonmal wer mit dieser Frage beschäftigt? Zu welchen Erkenntnissen seid ihr gelangt? Übersehe ich eine bessere Möglichkeit?