Первое: спасибо, что прочитали этот вопрос и пытаетесь мне помочь.Я новичок во всей теме потоков и сейчас сталкиваюсь с серьезной ошибкой взаимоблокировки mutex.
Краткое введение:
Я написал игровой движок несколько месяцев назад, который отлично работаети уже используется в играх.Этот движок основан на SDL2.Я хотел улучшить свой код, сделав его потокобезопасным, что было бы очень полезно для повышения производительности или для игры с некоторыми другими теоретическими концепциями.
Проблема:
В игре используется внутренняя играэтапы для отображения различных состояний игры, таких как отображение меню или отображение других частей игры.При входе в стадию «Игра астероидов» я получаю исключение, которое вызывается вызовом конструктора std :: lock_guard.
Проблема в деталях:
При входе в игру «Астероид»-стадия функции modelGetDirection () вызывается для получения вектора направления модели.Эта функция использует lock_guard, чтобы сделать эту функцию поточно-ориентированной.При отладке этого раздела кода именно здесь выдается исключение.Программа введет этот конструктор lock_guard и выдаст исключение.Странно то, что эта функция НИКОГДА не вызывается раньше.Это первый раз, когда вызывается эта функция, и каждый запуск теста завершается сбоем прямо здесь!
Здесь отладчик останавливается в threadx:
inline int _Mtx_lockX(_Mtx_t _Mtx)
{ // throw exception on failure
return (_Check_C_return(_Mtx_lock(_Mtx)));
}
А вот фактический кодфрагменты, которые я считаю важными:
структура мьютекса:
struct LEMutexModel
{
// of course there are more mutexes inside here
mutex modelGetDirection;
};
класс движка:
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):
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;
}
это игровая функция, которая использует метод modelGetDirection!Эта функция будет управлять космическим кораблем:
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
}
Таким образом, как уже упоминалось ранее: При входе в функцию level1ControlShip () программа войдет в функцию modelGetDirection ().При входе в функцию modelGetDirection () выдается исключение при попытке вызова:
lock_guard<mutex> lockA(this->mtxModel.modelGetDirection);
И, как уже упоминалось, это первый вызов этой функции во всем запуске приложения!
Так почему это?Я ценю любую помощь здесь!Весь движок (не игра) является проектом с открытым исходным кодом и может быть найден на gitHub на случай, если я забыл некоторые важные фрагменты кода (извините! В этом случае):
GitHub: Lynar Moon Engine
Спасибо за помощь!
Привет, Патрик