Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском».
Закрыт 10 месяцев назад.
Собственно проблема в полном умирании на операции join.
Вызывается из GUI, обработчик WM_COMMAND
class Test1
{
private:
bool _IsRun;
// volatile bool _IsRun; // без изменений
// std::atomic<bool> _IsRun; // без изменений
std::thread _thm;
void Test();
public:
Test1() : _IsRun(false) {}
~Test1() {}
...
};
void Test1::Test()
{
if (_IsRun)
{
_IsRun = false;
if (_thm.joinable())
_thm.join();
return;
}
_IsRun = true;
std::thread thw
{
[=]()
{
while (_IsRun)
{
....
}
_IsRun = false;
}
};
_thm = move(thw);
// std::swap(_thm, thw);
}
Понимаю что что-то делаю не так, но не соображу что.
В detach()
режиме работает как часы.. без _thm.joinable()
в блоке if
естественно ..
Upd:
Проблема все же найдена, поскольку в создаваемом потоке присутствуют long-time операции, то помогла проверка _IsRun
перед каждой из них. Общее впечатление, что если поток "задумался" на довольно продолжительное время во время ожидания (join) в GUI, то из этого состояния GUI просто не выйти.. При прохождении в отладке всего блока потока во время join
ошибок нет и всё завершается как запланированно. Особенности w10 ?
Всем спасибо кто уделил внимание этому вопросу, закрыть его не имею возможности.
С чего вы взяли, что "тред кончился"??? Нет, конечно. Ваш join
потому и "виснет", что тред не кончился и не кончится никогда.
Если _IsRun
- глобальная переменная, т.е. доступна функции потока напрямую, то из-за того, что она не объявлена volatile
, компилятор вправе генерировать код для функции потока в соответствии с логикой "если _IsRun
изначально был true
, то устраиваем бесконечный цикл, ибо поменяться _IsRun
уже никак не может". На это поведение могут влиять барьеры памяти и инструкции, неявно генерирующие такие барьеры, но полный код функции потока вы не привели.
Если _IsRun
- локальная переменная, то у вас функция потока захватывает переменные по значению, как вы сами явно попросили, т.е. у нее своя внутренняя копия переменной _IsRun
. Изменение внешней _IsRun
никак не влияет на внутреннюю копию, доступную функции потока.
Во первых нужно захватывать не по значению, а по ссылке. Вы в потоке просто копию _IsRun сделали. Копия изменения оригинала не видет. Во вторых std::atomic нужно. Иначе datarace. Если переменная не atomic (допустим даже компилятор ничего не оптимизировал), некоторое время после присваивания, разные ядра (соответственно разные потоки) могут видеть разные значения в переменной.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Условие:
Почему при попытки получить методы из интерфейса, пишет Cannot resolve method 'isProduct()' и Cannot resolve method 'getMenuTitle()'ourMenuItemsя прописываю как ArrayList
в проекте (spring boot + embedded tomcat) я использую jar файл в котором есть класс