Si consideri il seguente programma:C++: Termina chiamata, senza eccezione attiva (GCC)
#include <iostream>
#include <pthread.h>
#include <stdexcept>
#include <unistd.h>
static void* busy(void*)
{
int oldstate ;
auto result = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldstate) ;
if (result != 0)
#ifdef NOEXCEPT
{ std::cerr << "pthread_setcanceltype" << std::endl ; abort() ; }
#else
throw std::runtime_error("pthread_setcanceltype") ;
#endif
while (true)
;
return nullptr ;
}
static pthread_t start()
{
pthread_t t ;
int result = pthread_create(&t,nullptr,busy,nullptr) ;
if (result != 0)
throw std::runtime_error("pthread_create") ;
return t ;
}
static void terminate(pthread_t t)
{
auto result = pthread_cancel(t) ;
if (result != 0)
throw std::runtime_error("pthread_cancel()") ;
result = pthread_join(t,nullptr) ;
if (result != 0)
throw std::runtime_error("pthread_join()") ;
}
int main()
{
auto t = start() ;
sleep(1) ; // may not cause an abort otherwise
terminate(t) ;
return 0 ;
}
Questo funziona bene finché non l'ottimizzazione (o -O1) viene utilizzato, ad esempio, con g ++ -std = C++ 11 -Wall -o test test.cc -pthread
Tuttavia, con -O2 o -O3 il programma si interrompe con il messaggio sopra.
Anche un po 'interessante: viene eseguito se compilato con -DNOEXCEPT. Quindi, se una discussione viene cancellata in una funzione che potenzialmente [sic!] Genera un'eccezione, e se l'ottimizzazione è attivata, il programma potrebbe interrompersi. - E non riesco a vedere alcun modo per impedirlo.
È riproducibile per me su amd64 gcc 4.8.4 (Ubuntu 14.04.3) e armv7l gcc 4.9.2 (Raspbian 4.9.2-10).
Puoi riprodurre questo? Hai una spiegazione? Questo comportamento sembra strano (almeno per me). Sarei felice di ricevere una sorta di feedback. Grazie!
Credo che il posto si parla (si prega di collegamento quando ci si riferisce a qualcosa sul World Wide Web) stava parlando 'std :: thread' e non su pthreads. – molbdnilo
Un altro [articolo utile] (https://skaark.wordpress.com/2010/08/26/pthread_cancel-considered-harmful/). Sebbene non sia esattamente il tuo problema, delinea altri problemi con 'pthread_cancel'. Modifica: un altro [problema simile] (https://gcc.gnu.org/ml/gcc/2007-06/msg00020.html) –
Stai usando pthreads, non thread di C++ 11. Non c'è cancellazione del thread nei thread C++ 11. Il modo in cui i pthreads nudi interagiscono con le eccezioni C++ o con le funzionalità di thread C++ 11 (che probabilmente sono ancora pthreads all'interno della piattaforma, ma racchiuse in un qualche tipo di wrapper con C++), nessuno lo sa. –