Параллельное программирование на С++ в действии. Практика разработки многопоточных программ | страница 26
>thread_guard
, и в его деструкторе (2) происходит присоединение к потоку Это справедливо даже в том случае, когда выход из функции >f
произошел в результате исключения внутри функции >do_something_in_current_thread
.Деструктор класса >thread_guard
в листинге 2.3 сначала проверяет, что объект >std::thread
находится в состоянии >joinable()
(1) и, лишь если это так, вызывает >join()
(2). Это существенно, потому что функцию >join()
можно вызывать только один раз для данного потока, так что если он уже присоединился, то делать это вторично было бы ошибкой.
Копирующий конструктор и копирующий оператор присваивания помечены признаком >=delete
(3), чтобы компилятор не генерировал их автоматически: копирование или присваивание такого объекта таит в себе опасность, поскольку время жизни копии может оказаться дольше, чем время жизни присоединяемого потока. Но раз эти функции объявлены как «удаленные», то любая попытка скопировать объект типа >thread_guard
приведет к ошибке компиляции. Дополнительные сведения об удаленных функциях см. в приложении А, раздел А.2.
Если ждать завершения потока не требуется, то от проблемы безопасности относительно исключений можно вообще уйти, отсоединив поток. Тем самым связь потока с объектом >std::thread
разрывается, и при уничтожении объекта >std::thread
функция >std::terminate()
не будет вызвана. Но отсоединенный поток по-прежнему работает — в фоновом режиме.
2.1.4. Запуск потоков в фоновом режиме
Вызов функции-члeнa >detach()
объекта >std::thread
оставляет поток работать в фоновом режиме, без прямых способов коммуникации с ним. Теперь ждать завершения потока не получится — после того как поток отсоединен, уже невозможно получить ссылающийся на него объект >std::thread
, для которого можно было бы вызвать >join()
. Отсоединенные потоки действительно работают в фоне: отныне ими владеет и управляет библиотека времени выполнения С++, которая обеспечит корректное освобождение связанных с потоком ресурсов при его завершении.
Отсоединенные потоки часто называют потоками-демонами по аналогии с процессами-демонами в UNIX, то есть с процессами, работающими в фоновом режиме и не имеющими явного интерфейса с пользователем. Обычно такие потоки работают в течение длительного времени, в том числе на протяжении всего времени жизни приложения. Они, например, могут следить за состоянием файловой системы, удалять неиспользуемые записи из кэша или оптимизировать структуры данных. С другой стороны, иногда отсоединенный поток применяется, когда существует какой-то другой способ узнать о его завершении или в случае, когда нужно запустить задачу и «забыть» о ней.