Не `detach()` поток
Причина
Часто необходимость пережить область действия его создания присуща задаче thread, но реализация этой идеи через detach затрудняет мониторинг и общение с отделённым потоком. В частности, сложнее (хотя и возможно) убедиться, что поток завершился как положено или прожил столько, сколько ожидалось.
Пример
void heartbeat();
void use()
{
std::thread t(heartbeat); // don't join; heartbeat is meant to run forever
t.detach();
// ...
}
Это разумное использование потока, для которого detach() обычно используется. Однако есть проблемы. Как мы можем отслеживать отделённый поток, чтобы убедиться, что он живой? Что-то может пойти не так с биением сердца, и потеря удара может быть очень серьёзной в системе, для которой оно необходимо. Поэтому нам нужно общаться с потоком сердцебиения (например, через поток сообщений или события уведомления, используя condition_variable).
Альтернатива, и обычно лучшее решение — контролировать его жизненный цикл, поместив его в область действия вне его точки создания (или активации). Например:
void heartbeat();
gsl::joining_thread t(heartbeat); // heartbeat is meant to run "forever"
Это сердцебиение будет (при отсутствии ошибки, проблем с оборудованием и т.д.) работать столько, сколько работает программа.
Иногда нам нужно отделить точку создания от точки владения:
void heartbeat();
unique_ptr<gsl::joining_thread> tick_tock {nullptr};
void use()
{
// heartbeat is meant to run as long as tick_tock lives
tick_tock = make_unique<gsl::joining_thread>(heartbeat);
// ...
}
Применение
Отмечайте detach().