Предположим, я запускаю a, std::thread
а затем detach()
it, поэтому поток продолжает выполняться, даже если тот, std::thread
который когда-то представлял его, выходит из области видимости.
Предположим далее, что программа не имеет надежного протокола для присоединения к отсоединенному потоку 1 , поэтому отсоединенный поток по-прежнему работает при main()
выходе.
Я не могу найти ничего в стандарте (точнее, в проекте N3797 C ++ 14), который описывает, что должно произойти, ни 1.10, ни 30.3 не содержат соответствующих формулировок.
1 Другой, возможно, эквивалентный вопрос: «можно ли когда-нибудь снова присоединить отсоединенный поток», потому что к какому бы протоколу вы ни придумали присоединиться, сигнальная часть должна была быть выполнена, пока поток еще работал, и планировщик ОС мог бы решите перевести поток в спящий режим на час сразу после того, как была выполнена сигнализация, и принимающая сторона не сможет надежно определить, что поток действительно завершен.
Если завершение работы main()
с отсоединенными потоками является неопределенным поведением, тогда любое использование std::thread::detach()
является неопределенным поведением, если только основной поток никогда не завершает работу 2 .
Таким образом, завершение работы main()
с отсоединенными потоками должно иметь определенные эффекты. Вопрос в том, где (в стандарте C ++ , а не в POSIX, не в документации по ОС, ...) определяются эти эффекты.
2 Отдельная нить не может быть соединена (в смысле std::thread::join()
). Вы можете ждать результатов от отсоединенных потоков (например, через будущее std::packaged_task
или с помощью счетного семафора или флага и переменной условия), но это не гарантирует, что поток завершил выполнение . В самом деле, если не поставить сигнализацию части в деструктор первого автоматического объекта потока, там будет , вообще говоря , код (деструкторы) , которые выполняются после кода сигнализации. Если ОС планирует, что основной поток получит результат и завершит работу до того, как отдельный поток завершит работу с указанными деструкторами, что будет определяться ^ W?
std::exit
или выходом изmain
него достаточно, но не обязательно, чтобы удовлетворить эти требования». (весь абзац может быть релевантным) Также см. [support.start.term] / 8 (std::exit
вызывается, когдаmain
возвращается)