Non ho bisogno di terminare correttamente il thread o farlo rispondere a un comando "termina". Sono interessato a terminare forzatamente il thread utilizzando C ++ 11 puro.
Non ho bisogno di terminare correttamente il thread o farlo rispondere a un comando "termina". Sono interessato a terminare forzatamente il thread utilizzando C ++ 11 puro.
Risposte:
Puoi chiamare std::terminate()
da qualsiasi thread e il thread a cui ti riferisci terminerà forzatamente.
È possibile disporre l' ~thread()
esecuzione sull'oggetto del thread di destinazione, senza intervenire join()
né detach()
su quell'oggetto. Ciò avrà lo stesso effetto dell'opzione 1.
È possibile progettare un'eccezione che ha un distruttore che genera un'eccezione. E quindi organizzare che il thread di destinazione generi questa eccezione quando deve essere terminato forzatamente. La parte difficile di questo è ottenere il thread target per lanciare questa eccezione.
Le opzioni 1 e 2 non perdono risorse interne al processo, ma terminano ogni thread.
L'opzione 3 probabilmente perderà risorse, ma è parzialmente cooperativa in quanto il thread target deve accettare di lanciare l'eccezione.
In C ++ 11 (di cui sono a conoscenza) non esiste un modo portatile per uccidere in modo non cooperativo un singolo thread in un programma multi-thread (ovvero senza uccidere tutti i thread). Non c'era motivazione per progettare una tale caratteristica.
A std::thread
può avere questa funzione membro:
native_handle_type native_handle();
Potresti essere in grado di utilizzarlo per chiamare una funzione dipendente dal sistema operativo per fare ciò che desideri. Ad esempio sui sistemi operativi Apple, questa funzione esiste ed native_handle_type
è a pthread_t
. Se si riesce, è probabile che si verifichino perdite di risorse.
std::terminate
né chiama distruttori statici né svuota i buffer di output, quindi l'ordine in cui vengono rilasciate le risorse non è ben definito, né hai alcuna garanzia che i tuoi dati siano visibili all'utente o scritti in un archivio permanente, o addirittura coerente e completo.
exit()
o abort()
allo stesso effetto complessivo.
La risposta di @Howard Hinnant è sia corretta che completa. Ma potrebbe essere frainteso se viene letto troppo rapidamente, perché std::terminate()
(l'intero processo) sembra avere lo stesso nome del "termine" che @AlexanderVX aveva in mente (1 thread).
Riepilogo: "termina 1 thread + forzatamente (il thread target non collabora) + pure C ++ 11 = Assolutamente no."
std::terminate()
risposta è come una classica malvagia storia di Djinn; soddisfa tutto il desiderio del PO alla lettera, anche se probabilmente non nel modo in cui intendeva . L'umorismo discreto mi ha fatto sorridere. :-)
Questa domanda in realtà ha una natura più profonda e una buona comprensione dei concetti di multithreading in generale ti fornirà informazioni su questo argomento. In effetti, non esiste alcuna lingua o alcun sistema operativo che fornisca servizi per la terminazione brusca asincrona del thread senza preavviso per non usarli. E tutti questi ambienti di esecuzione consigliano vivamente lo sviluppatore o richiedono persino la creazione di applicazioni multithreading sulla base della terminazione di thread cooperativa o sincrona. Il motivo di queste decisioni e consigli comuni è che tutti sono costruiti sulla base dello stesso modello di multithreading generale.
Confrontiamo i concetti di multiprocessing e multithreading per comprendere meglio i vantaggi e i limiti del secondo.
Il multiprocessing presuppone la suddivisione dell'intero ambiente di esecuzione in una serie di processi completamente isolati controllati dal sistema operativo. Il processo incorpora e isola lo stato dell'ambiente di esecuzione, compresa la memoria locale del processo e dei dati al suo interno e tutte le risorse di sistema come file, socket, oggetti di sincronizzazione. L'isolamento è una caratteristica di fondamentale importanza del processo, poiché limita la propagazione dei guasti da parte dei bordi del processo. In altre parole, nessun processo può influire sulla coerenza di un altro processo nel sistema. Lo stesso vale per il comportamento del processo, ma nel modo meno limitato e più sfocato. In tale ambiente qualsiasi processo può essere interrotto in qualsiasi momento "arbitrario", poiché in primo luogo ogni processo è isolato, in secondo luogo,
Al contrario, il multithreading presuppone l'esecuzione di più thread nello stesso processo. Ma tutti questi thread condividono la stessa casella di isolamento e non esiste alcun controllo del sistema operativo sullo stato interno del processo. Di conseguenza, qualsiasi thread è in grado di modificare lo stato del processo globale e di corromperlo. Allo stesso tempo, i punti in cui è noto che lo stato del thread è sicuro per eliminare completamente un thread dipende dalla logica dell'applicazione e non sono noti né per il sistema operativo né per il runtime del linguaggio di programmazione. Di conseguenza, terminare il thread nel momento arbitrario significa ucciderlo in un punto arbitrario del suo percorso di esecuzione e può facilmente portare alla corruzione dei dati a livello di processo, alla memoria e alla gestione delle perdite,
Per questo motivo l'approccio comune è quello di forzare gli sviluppatori a implementare la terminazione di thread sincrona o cooperativa, in cui un thread può richiedere la terminazione di altri thread e l'altro thread in un punto ben definito può controllare questa richiesta e avviare la procedura di arresto dallo stato ben definito rilasciando tutte le risorse globali a livello di sistema e le risorse locali a livello di processo in modo sicuro e coerente.
Suggerimenti sull'uso della funzione dipendente dal sistema operativo per terminare il thread C ++:
std::thread::native_handle()
può solo ottenere il tipo di handle nativo valido del thread prima di chiamare join()
o detach()
. Dopodiché, native_handle()
restituisce 0 - pthread_cancel()
verrà coredump.
Per chiamare in modo efficace la funzione di terminazione del thread nativo (ad es. pthread_cancel()
), È necessario salvare l'handle nativo prima di chiamare std::thread::join()
o std::thread::detach()
. In modo che il terminatore nativo abbia sempre un handle nativo valido da utilizzare.
Ulteriori spiegazioni si prega di fare riferimento a: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .
Immagino che il thread che deve essere ucciso sia in qualsiasi tipo di modalità di attesa o che faccia un lavoro pesante. Suggerirei di usare un modo "ingenuo".
Definisci alcuni booleani globali:
std::atomic_bool stop_thread_1 = false;
Inserisci il seguente codice (o simile) in diversi punti chiave, in modo da far tornare tutte le funzioni nello stack di chiamate fino a quando il thread non termina naturalmente:
if (stop_thread_1)
return;
Quindi per interrompere il thread da un altro thread (principale):
stop_thread_1 = true;
thread1.join ();
stop_thread_1 = false; //(for next time. this can be when starting the thread instead)