Suponha que eu esteja iniciando um std::thread
e depois detach()
, para que o encadeamento continue sendo executado, mesmo que o std::thread
que antes o representasse saia do escopo.
Suponha ainda que o programa não tenha um protocolo confiável para ingressar no encadeamento desanexado 1 ; portanto, o encadeamento desanexado ainda será executado quando main()
sair.
Não consigo encontrar nada no padrão (mais precisamente, no rascunho do N3797 C ++ 14), que descreve o que deveria acontecer, nem 1.10 nem 30.3 contêm palavras pertinentes.
1 Outra pergunta, provavelmente equivalente, é: "um encadeamento desanexado pode ser unido novamente", porque, independentemente do protocolo que você está inventando para ingressar, a parte de sinalização precisa ser feita enquanto o encadeamento ainda está em execução e o agendador do SO pode decida colocar o encadeamento em suspensão por uma hora logo após a sinalização, sem que o destinatário possa detectar com segurança que o encadeamento realmente terminou.
Se a execução de main()
threads desanexados estiver executando um comportamento indefinido, qualquer uso de std::thread::detach()
é um comportamento indefinido, a menos que o thread principal nunca saia 2 .
Portanto, a execução de main()
threads desanexados em execução deve ter efeitos definidos . A questão é: onde (no padrão C ++ , não POSIX, nem documentos do SO, ...) são esses efeitos definidos.
2 Um encadeamento desanexado não pode ser unido (no sentido de std::thread::join()
). Você pode aguardar resultados de threads desanexados (por exemplo, através de um futuro de std::packaged_task
, ou por um semáforo de contagem ou um sinalizador e uma variável de condição), mas isso não garante que o thread tenha terminado de executar . Na verdade, a menos que você colocar a parte de sinalização para o destruidor do primeiro objeto automático do fio, não será , em geral, seja de código (destruidores) que são executados após o código de sinalização. Se o SO agendar o encadeamento principal para consumir o resultado e sair antes que o encadeamento desanexado conclua a execução dos destruidores, o que ^ Wis definirá para acontecer?
std::exit
ou saídamain
é suficiente, mas não necessário, para atender a esses requisitos". (o parágrafo inteiro pode ser relevante) Veja também [support.start.term] / 8 (std::exit
é chamado quandomain
retorna)