Supponiamo che io stia iniziando un std::thread
e quindi detach()
, quindi il thread continua l'esecuzione anche se quello std::thread
che una volta lo rappresentava, va fuori portata.
Supponiamo inoltre che il programma non disponga di un protocollo affidabile per unire il thread separato 1 , quindi il thread disconnesso continua a funzionare quando main()
esce.
Non riesco a trovare nulla nello standard (più precisamente, nella bozza N3797 C ++ 14), che descrive cosa dovrebbe accadere, né 1.10 né 30.3 contengono una formulazione pertinente.
1 Un'altra domanda, probabilmente equivalente, è: "è possibile unire nuovamente un thread separato", poiché qualsiasi protocollo si stia inventando per unirsi, la parte di segnalazione dovrebbe essere eseguita mentre il thread era ancora in esecuzione e lo scheduler del sistema operativo potrebbe decidere di mettere in pausa il thread per un'ora subito dopo l'esecuzione della segnalazione senza che l'estremità ricevente rilevi in modo affidabile che il thread sia effettivamente terminato.
Se l'esaurimento main()
con l'esecuzione di thread separati è un comportamento indefinito, qualsiasi uso di std::thread::detach()
è un comportamento indefinito a meno che il thread principale non esca mai 2 .
Pertanto, a corto di main()
thread separati in esecuzione deve avere effetti definiti . La domanda è: dove (nello standard C ++ , non POSIX, non documenti del sistema operativo, ...) sono definiti quegli effetti.
2 Un thread separato non può essere unito (nel senso di std::thread::join()
). È possibile attendere i risultati da fili indipendenti (ad esempio tramite un futuro da std::packaged_task
, o da un semaforo conteggio o una bandiera e una variabile condizione), ma che non garantisce che il filo ha terminato l'esecuzione . Infatti, a meno che non si inserisca la parte di segnalazione nel distruttore del primo oggetto automatico del thread, ci saranno , in generale, dei codici (distruttori) che corrono dopo il codice di segnalazione. Se il sistema operativo pianifica il thread principale per consumare il risultato e uscire prima che il thread separato abbia terminato l'esecuzione di detti distruttori, che cosa verrà definito?
std::exit
o uscire damain
è sufficiente, ma non necessario, per soddisfare questi requisiti." (l'intero paragrafo può essere pertinente) Vedi anche [support.start.term] / 8 (std::exit
viene chiamato quandomain
ritorna)