000
23.05.2018, 11:48 Uhr
LynarStudios
|
Hey!
Zunächst: Danke, dass du dieses Thema liest und mir versuchst bei meinem Problem zu helfen. Das ganze Thema threading ist ziemlich neu für mich.
Kurze Einführung:
Ich habe vor einigen Monaten eine Game Engine geschrieben, die auch sehr gut läuft und in Spielen bereits verwendet wird. Die Engine baut auf SDL2 auf. Ich möchte nun die Engine thread safe machen, um die Performance zu verbessern und auch mit anderen theoretischen Konzepten rumspielen zu können.
Das Problem:
Das Spiel benutzt intern Zustandswerte, um zu erkennen in welchem Teil des Spieles es sich befindet, wie etwa einen Wert für das Anzeigen des Menüs, oder auch für andere Inhalte des Spieles. Wird der Wert "Asteroid Level" erreicht (ein kleiner Teil des Spieles) wird eine exception geworfen, wenn std::lock_guard aufgerufen wird.
Das Problem im Detail:
Wird das "Asteoriden Level" erreicht, wird eine modelGetDirection() Funktion aufgerufen, die einen 2D Vektor zurück gibt. Diese Funktion nutzt einen lock_guard, um thread safe zu sein. Wenn ich die ganze Anwendung debugge, weiß ich, dass genau bei diesem Aufruf eine exception geworfen wird. Das merkwürdige ist, dass diese Funktion, und somit auch der mutex niemals vorher aufgerufen wird. Jedes Mal, wenn ich das Programm teste crasht das Programm genau an dieser Stelle.
Das ist die Stelle, wo der Debugger in threadx stoppt:
C++: |
inline int _Mtx_lockX(_Mtx_t _Mtx) { // throw exception on failure return (_Check_C_return(_Mtx_lock(_Mtx))); }
|
Das ist die exception:
Zitat: |
Exception thrown at 0x00007FF9181B0B03 (msvcp140d.dll) in SolarLight.exe: 0xC0000005: Access violation reading location 0x00000020000AFF18.
|
Und das hier sind die eigentlich Code - Abschnitte, von denen ich glaube, dass sie wichtig sind:
mutex struct:
C++: |
struct LEMutexModel { // of course there are more mutexes inside here mutex modelGetDirection; };
|
engine Klasse:
C++: |
typedef class LEMoon { private: LEMutexModel mtxModel;
// other mutexes, attributes, methods and so on
public:
glm::vec2 modelGetDirection(uint32_t, uint32_t);
// other methods } *LEMoonInstance;
|
modelGetDirection() - engine Definition:
C++: |
glm::vec2 LEMoon::modelGetDirection(uint32_t id, uint32_t idDirection) { lock_guard<mutex> lockA(this->mtxModel.modelGetDirection); glm::vec2 direction = {0.0f, 0.0f}; LEModel * pElem = this->modelGet(id); if(pElem == nullptr) {pElem = this->modelGetFromBuffer(id);}
if(pElem != nullptr) {direction = pElem->pModel->mdlGetDirection(idDirection);} else { #ifdef LE_DEBUG char * pErrorString = new char[256 + 1]; sprintf(pErrorString, "LEMoon::modelGetDirection(%u)\n\n", id); this->printErrorDialog(LE_MDL_NOEXIST, pErrorString); delete [] pErrorString; #endif } return direction; }
|
Das ist die Funktion, wo modelGetDirection() aufgerufen wird:
C++: |
void Game::level1ControlShip(void * pointer, bool controlAble) { Parameter param = (Parameter) pointer; static glm::vec2 currentSpeedLeft = {0.0f, 0.0f}; glm::vec2 speedLeft = param->engine->modelGetDirection(MODEL_VERA, LEFT); static const double INCREASE_SPEED_LEFT = (1.0f / VERA_INCREASE_LEFT) * speedLeft.x * (-1.0f); // ... more code, I think that's not important }
|
Wie bereits erwähnt: Wenn die Funktion level1ControlShip() aufgerufen wird, wird die Funktion modelGetDirection() aufgerufen. Wird modelGetDirection() aufgerufen wird direkt eine exception geworfen bei dem Versuch diesen lock_guard aufzurufen:
C++: |
lock_guard<mutex> lockA(this->mtxModel.modelGetDirection);
|
Es ist das erste Mal, dass die Funktion modelGetDirection() und somit auch dieser mutex benutzt wird. Was ist also das Problem? Ich sitze schon seit einer Weile an dieser Lösung. Klar ist auch, dass das Programm keine Exception wirft, wenn die Funktion level1ControlShip() nicht aufgerufen wird.
Über jede Hilfe wäre ich sehr, sehr dankbar.
Die Game Engine (nicht das Spiel) ist übrigens ein open source Projekt und auf gitHub verfügbar, sollte ich wichtigen Code vergessen haben:
https://github.com/LynarStudios/LEMoon
Vielen Dank schon einmal!
Gruß, Patrick Dieser Post wurde am 23.05.2018 um 11:51 Uhr von LynarStudios editiert. |