std :: lock_guard (mutex) создает тупик - PullRequest
0 голосов
/ 23 мая 2018

Первое: спасибо, что прочитали этот вопрос и пытаетесь мне помочь.Я новичок во всей теме потоков и сейчас сталкиваюсь с серьезной ошибкой взаимоблокировки 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

Спасибо за помощь!

Привет, Патрик

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...