Threading

Liebes Forum!

Seit einigen Monaten beschäftige ich mich jetzt mit einer Art kleinen „Grafikengine“. Zumindest soll es das einmal werden.
Zur Zeit wird das ganze Programm in einer großen Schleife abgearbeitet. (basierend auf den NeHe Tutorials) Bislang lief alles problemlos, die Positionen etc. wurden alle aus den Abständen zum letzten Frame errechnet, upgedated und schließlich wieder gezeichnet.

Jetzt kommt aber etwas neues dazu, der Zeitfaktor. Derzeit sind es noch kleinere Sachen, wie die MouseLeaf und MouseEnter Events bei meinen Steuerelementen, die ich demnächst implementieren möchte, aber später werden dann auch Dinge kommen, wie Client und Server, da das aus diesem Projekt entstehende Spiel auch über ein Netzwerk gespielt werden können sollte. Jetzt ist natürlich wichtig, dass Daten in regelmäßigen Abständen ausgetauscht werden müssen (Spielerpositionen, Blickvektor, etc.). Sollte ich dann auch noch so weit kommen einen richtigen Shooter darauszumachen, muss es auch Waffen geben und die müssen in regelmäßigen Abständen feuern, abhängig vom Status der Maustaste. (am besten an CS denken)

Jetzt stell ich mir schon jetzt die Frage, wie ich das ganze organisieren möchte. Ich habe also meinen MainLoop. Hier wird auch gezeichnet. Der MeinLoop läuft auf meinem PC ziemlich exakt 60 mal pro Sekunde. Auf den PCs in unserer Schule um die 450 mal pro Sekunde und auf einem alten Laptop mit nur 15 Durchläufen. Unabhängig davon, wie viele FPS errechnet werden, müssen sagen wir alle 10ms Daten übers Netzwerk gesendet werden. Es mussen alle Abgegebenen Schüsse zum Server übertragen werden und dort muss verrechnet werden, ob man jemanden getroffen hat, und das Ergebnis den Clienten mitgeteilt werden. Diese müssen die Daten annehmen und die Szene demnach entsprechend zeichnen.

Ich denke mal, ich werde um Multithreading nicht herumkommen, obwohl sich alles bisher so wunderschön in einem Thread lösen hat lassen.

Dann würde ich das mit zwei Threads machen. Einen Zeichenthread, der nur die Szene zeichnet und die Grafikaufrufe erledigt und einen Rechenthread, der die Daten vom Server annimmt, Tastatureingaben, Maus, etc. verrechnet, Playerpositionen aktualisiert, Sounds wiedergibt usw.

Was meint ihr dazu? Hätte jemand einen guten Vorschlag wie man das vielleicht bessa lösen könnte?

Es wäre auch toll, wenn mir jemand einen guten Tipp Multithreading geben kann, was da am besten für mich wäre. Sollte am besten auf Windows als auch auf Linux einsatzfähig sein. Vorerst reicht mir Windows aber aus.

Da fällt mir noch was ein. Wenn ich Zwei Threads laufen lasse, wie oben beschrieben, dann hab ich das Problem, dass es passieren kann, dass während der Rechenthread die Positionen neu berechnet, der Zeichenthread bereits mit den Grafikaufrufen beginnt und die Vertices entsprechend den Werten des Rechenthreads setzt. Wenn sich das ganze jetzt so überschneidet kommt höchstwahrscheinlich nicht das gewünschte Ergebnis heraus. Kann ich den Rechenthread alleine laufen lassen und nur in den Abständen, in denen die Grafikkarte ein neues Frame benötigt (alle 1/60 s) den Zeichenthread laufen lassen?

Wäre für ein paar Ideen sehr dankbar!
mfg dixxi

Hi dixxi!
Ich habe mal deine Frage durchgelesen und zufälligerweise beschäfftige ich mich momentan mit mit Multithreading. Leider kenne ich mich mit Spieleprogrammierung nicht wirklich aus.

Zur Multithreading: 1) Mir ist keine Bib. bekannt, dass sowohl für Linux als auch für Windows einsetzbar währe. Aber ich würde hier erstmal mit einem von den beiden beginnen. Denn das Multithreading ist ein Thema, dass auf den ersten Blick nicht wirklich schwer ist aber die Umsetzung doch zu vielen schwer nachvollziehbaren Problemmen führt.

Ansich denke ich dass ein thread für die Grafik, ein Thread für Berechnungen und Threads für die Verbindungen Sinnvoll ist. (Ist aber nur meine Meinung).

Das Problem was dir bereits aufgefallen ist, ist die Sychronisierungsproblemmatik. Es gibt bei jedem (mehr oder minder vernünftigen) OS Funktionen die dir Synchronisation der Threads ermöglichen. Beispiel: Mutex, Simophore, CRITICAL_SECTION, … um einige aus Win32 Welt zu nennen.
Weitere Problematik ist ein Weg zu finden, dass die Threads nicht sich gegenseitig ausblocken (Deadlock). Beispiel: Thread 1 wartet auf Thread 2 bis er fertig ist. Thread 2 jedoch breauch ein Ergebnis von Thread 1 aus wartet auf diesen. So warten diese Threads für die Ewigkeit :smile:
Durch ein von Anfag an gut geplanntes Konzept lassen sich solche Problemme lösen. In diesem Konzept sollte auch berücksichtigt werden, dass es nicht zu stark synchronisiert wird. Sonst laufen alle Threads hintereinander und du hast nichts gewonnen.
Nun noch ein Tip: Benutze keine statischen Variabelen ohne den Zugriff auf diese Datenobjekte zu synchronisieren! (Eigentlich vermeide grundsätzlich statische Variablen).

Noch ein Tip zum beginnen: Schreibe erst mal ein simples Programm mit mehreren Threads, so das du ein Gefühl für diese entwickelst und die Apis kennenlernst!
Die Multithreading Apies sind in MSDN zu finden, wie alle anderen auch :smile:

Hoffe dir ein wenig geholfen zu haben.

Gruß

Andreas

Zur Multithreading: 1) Mir ist keine Bib. bekannt, dass sowohl
für Linux als auch für Windows einsetzbar währe.

Das Thread-Paket aus der Boost-Bibliothek (http://www.boost.org/) wäre vermutlich sehr gut geeignet:

http://www.boost.org/doc/libs/1_37_0/doc/html/thread…

Wenn ich den Text am Ende der Seite richtig interpretiere, ist Boost.Thread in seiner aktuellen Fassung für die nächste C+±Version zur Standardisierung eingereicht. D.h. man macht es damit gleich „richtig“ für die Zukunft.

Viele Grüße,
Sebastian

ok vielen dank!

Wenn ich den Text am Ende der Seite richtig interpretiere, ist
Boost.Thread in seiner aktuellen Fassung für die nächste
C+±Version zur Standardisierung eingereicht. D.h. man macht
es damit gleich „richtig“ für die Zukunft.

Gut, dann sollte ich mir das demnächst einmal anschauen. Vielen Dank für den Tipp!

mfg dixxi