Boost :: thread mutex проблема: попытка блокировки, нарушение прав доступа

В настоящее время я учусь многопоточности с C ++, и для этого я использую Boost :: Thread.
Я использую его для простого игрового движка, запускающего три потока.

Два потока читают и записывают в одни и те же переменные, которые хранятся внутри чего-то, что я называю PrimitiveObjects, в основном шары, тарелки, коробки и т. Д.

Но я не могу заставить его работать, я думаю, проблема в том, что два потока пытаются получить доступ к одному и тому же месту в памяти одновременно, я пытался избежать этого с помощью мьютекс-блокировок, но сейчас мне не повезло, это работает несколько раз, но если я спам, я в конечном итоге с этим исключением:

First-chance exception at 0x00cbfef9 in TTTTT.exe: 0xC0000005: Access violation reading location 0xdddddded.
Unhandled exception at 0x77d315de in TTTTT.exe: 0xC0000005: Access violation reading location 0xdddddded.

Это функции внутри объекта, которые я использую для этого, и отладчик также обвиняет их в исключении.

int PrimitiveObj::setPos(glm::vec3 in){
boost::try_mutex::scoped_try_lock lock(myMutex);
if ( lock)
{
position = in;
return 1;
}
return 0;
}

glm::vec3 PrimitiveObj::getPos(){
boost::try_mutex::scoped_try_lock lock(myMutex);
if ( lock)
{
glm::vec3 curPos = position;
return curPos;
}
return glm::vec3(0,0,0);
}

Это функция, которую я использую для генерации каждого примитива. (Обновлено)

void generatePrimitive(){
PrimitiveObj *obj = new PrimitiveObj();
obj->generate();
obj->setPos(getPlayerPos()+getEye()*4.0f);
prims.push_back(std::shared_ptr<PrimitiveObj>(obj));
}

Снимок экрана

Есть идеи?
Редактировать: Новые функции (2), и myMutex теперь является приватным для объекта. Добавлена ​​функция, которую я использую для генерации примитивных объектов.

ошибка

Редактировать:

Это код, на который указывает стек, и он выполняется внутри физического потока:

nr = getNumberOfPrimitives();

double currentTime = glfwGetTime();
float deltaTime = float(currentTime - lastTime);
for(int r = 0; r < nr; r++) {prop = getPrimitive(r);
glm::vec3 pos = prop->getPos()+glm::vec3(0,1.0f*Meter/deltaTime,0);

prop->setPos(pos);

}

Другой соответствующий код:

int getNumberOfPrimitives(){
return prims.size();
}

PrimitiveObj * getPrimitive(int input) {
return prims[input];
}

3

Решение

Первая идея заключается в том, что ваш PrimitiveObj то, что вы звоните, неинициализировано, что-то вроде этого:

PrimitiveObj* myObject;
myObject->getPos();

Исключением является то, что вы, скорее всего, обращаетесь к неинициализированной переменной-указателю (равной 0xdddddddd, чтобы разработчик распознал ее как неинициализированную) и обращаетесь к элементу, который смещен на 0x10 (= 16) байтов.

Исключения доступа также могут возникать, если вы обращаетесь к объектам, таким как std: vector, при чтении и записи из разных потоков в один и тот же объект в одно и то же время, но часто это более случайное число, которое начинается с нулей и делится на 4 ( например, 0x004da358).

Почему это так? Код отладки часто инициализирует память некоторыми узнаваемыми, но случайными числами (0xdddddddd, 0xbaadfood, 0xfefefefe и т. Д.). Они случайны, потому что если переменные всегда будут одинаковыми, например, всегда инициализируется 0, что может привести к тому, что разработчик упустит тот факт, что некоторые переменные не инициализированы и код перестанет работать в выпуске. Их легко распознать, поэтому мы можем сразу увидеть, что число исходит из неинициализированной памяти.

Ранее действительные указатели указывают на адресное пространство кучи, которое обычно начинается с несколько меньшего числа и подсчитывается. Если в куче размещено несколько объектов, при нормальной работе каждый объект выравнивается по адресу памяти, кратному 4, 8, 16 и т. Д., Члены объекта также выравниваются по 4-байтовым границам, поэтому нарушения доступа вызвали при доступе к ранее действительной памяти часто на адреса, которые начинаются с нулей и делятся на 4.

Помните, что это эмпирические правила, которые можно и нужно использовать, чтобы указать вам правильное направление, но они не являются жесткими и быстрыми правилами. Также они относятся к средам отладки. В средах выпуска очень разные правила, чтобы угадать, какое нарушение прав доступа вызвано чем.

2

Другие решения

Других решений пока нет …