Я пытаюсь изящно очиститься при завершении программы, поэтому я вызываю join()
на std::thread
, чтобы дождаться ее завершения. Это просто блокирует основной поток навсегда, но я не понимаю, почему, потому что рабочий поток представляет собой (почти) пустой цикл, подобный этому:
void GameLoop::Run()
{
while (run)
{
// Do stuff...
}
std::cout << "Ending thread...\n";
}
Я устанавливаю run
в false перед join
ing, конечно. Теперь я подозреваю, что это как-то связано с тем, что это функция-член и вызывается при уничтожении объекта. Я создаю ветку так: runThread.reset(new thread(&GameLoop::Run, this));
, где runThread
это unique_ptr<std::thread>
и член GameLoop
. Вызов join()
поступает в деструктор объекта GameLoop
.
Может быть, поток цикла не может завершиться, если его объект находится в процессе уничтожения? Согласно отладчику, нить цикла задерживается в темных глубинах msvcr120d.dll
. Если да, то как бы вы с этим справились?
Осторожно: новинка std::thread
здесь!
Обновление: Это мой призыв присоединиться к деструктору:
run = false;
if (runThread->joinable())
{
runThread->join();
}
Обновление 2: если я удалю join()
, я получу исключение, вызванное ~thread()
!
run
вfalse
? Что делает присоединение к потоку, так это усыпляет вызывающий поток до тех пор, пока целевой поток не умрет (с его различными значениями), что вы и видите. Это не убивает сам поток. - person Blindy   schedule 13.11.2013thread::joinable
, если поток не может быть присоединен, вам, очевидно, не следует присоединяться к нему. Что произойдет, если вы удалите соединение? Если программа закрывается нормально (проверьте диспетчер задач), это означает, что поток был успешно очищен компилятором. - person Blindy   schedule 13.11.2013std::atomic
.volatile
не имеет переносимой семантики и бесполезен для синхронизации между потоками. - person Pete Becker   schedule 13.11.2013