std :: thread :: detach вызывает сбой после уничтожения оригинального абонента

struct Test {
bool active{true};

void threadedUpdate() {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!active) // crashes here after Test instance is destroyed
return;
}

Test() {
std::thread([this]{ while(true) threadedUpdate(); }).detach();
}

~Test() {
// somehow stop the detached thread?
}
};

Когда экземпляр Test инициализируется, порождает и отключает std::thread который работает в фоновом режиме. Когда тот же экземпляр уничтожен, ранее упомянутый поток пытается получить доступ к active член, который был уничтожен вместе с экземпляром, вызывая сбой (и AddressSanitizer трассировка).

Есть ли способ стоп оторванная нить на ~Test()?

Дизайн плохой. Как правильно создать / обработать поток, работающий в фоновом режиме, пока вызывающая сторона не будет уничтожена?

7

Решение

Сделайте поток членом класса, и вместо того, чтобы отделять его в конструкторе, присоедините его в деструкторе. Чтобы остановить цикл от потока, вы можете иметь внутри класса логическое значение, которое сигнализирует, должен ли поток продолжать работать или нет (std::atomic<bool> update).

Поток может выполнять это: [this] { while (update) threadUpdate(); },

В деструкторе вашего класса update = falseи позвоните thread.join()

12

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

Вы не можете остановить отдельные темы. В этом суть .detach() — у тебя нет любой способ ссылаться на отдельный поток больше, по крайней мере, так, как указано в стандарте C ++. Если вы хотите сохранить дескриптор потока, сохраните std::thread и позвонить .join() в деструкторе.

7

По вопросам рекламы [email protected]