Come posso terminare una discussione in C ++ 11?

Non è necessario terminare correttamente il thread o farlo rispondere a un comando “termina”. Sono interessato a terminare il thread forzatamente usando puro C ++ 11.

  1. Potresti chiamare std::terminate() da qualsiasi thread e il thread a cui ti riferisci terminerà forzatamente.

  2. È ansible disporre che ~thread() sia eseguito sull’object del thread di destinazione, senza un join() né un detach() su quell’object. Questo avrà lo stesso effetto dell’opzione 1.

  3. È ansible progettare un’eccezione con un distruttore che genera un’eccezione. E quindi organizzare il thread di destinazione per lanciare questa eccezione quando deve essere forzatamente terminata. La parte difficile su questo è ottenere il thread di destinazione per lanciare questa eccezione.

Le opzioni 1 e 2 non perdono le risorse intra-processo, ma interrompono ogni thread.

L’opzione 3 probabilmente perderà risorse, ma è parzialmente cooperativa in quanto il thread di destinazione deve accettare l’eccezione.

Non c’è un modo portabile in C ++ 11 (che io sappia) per non uccidere in modo cooperativo un singolo thread in un programma multi-thread (cioè senza uccidere tutti i thread). Non c’era alcuna motivazione per progettare una funzione del genere.

Una std::thread può avere questa funzione membro:

 native_handle_type native_handle(); 

Potresti essere in grado di usarlo per chiamare una funzione dipendente dal sistema operativo per fare ciò che desideri. Ad esempio, sui SO di Apple, questa funzione esiste e native_handle_type è un pthread_t . Se hai successo, è probabile che perderai risorse.

La risposta di @Howard Hinnant è sia corretta che completa. Ma potrebbe essere frainteso se viene letto troppo velocemente, perché std::terminate() (intero processo) ha lo stesso nome del “terminating” che @AlexanderVX aveva in mente (1 thread).

Riepilogo: “terminare 1 thread + con forza (il thread di destinazione non collabora) + puro C ++ 11 = Assolutamente no.”

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 sistema operativo che fornisca servizi per la chiusura asincrona del thread senza preavviso per non utilizzarli. E tutti questi ambienti di esecuzione consigliano vivamente lo sviluppatore o addirittura richiedono la creazione di applicazioni multithreading sulla base della terminazione cooperativa o sincrona del thread. La ragione di queste decisioni e dei consigli comuni è che tutti sono costruiti sulla base dello stesso modello generale di multithreading.

Confrontiamo i concetti di multiprocessing e multithreading per comprendere meglio i vantaggi e i limiti del secondo.

Il multiprocessing presuppone la divisione dell’intero ambiente di esecuzione in un insieme 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, perché limita la propagazione dei difetti dai confini del processo. In altre parole, nessun processo può influire sulla coerenza di nessun altro processo nel sistema. Lo stesso vale per il comportamento del processo, ma nel modo meno ristretto e più sfocato. In tale ambiente qualsiasi processo può essere ucciso in qualsiasi momento “arbitrario”, perché in primo luogo ogni processo è isolato, in secondo luogo, il sistema operativo ha piena conoscenza di tutte le risorse utilizzate dal processo e può rilasciarle tutte senza perdite e infine il processo verrà ucciso dal sistema operativo non proprio in un momento arbitrario, ma nel numero di punti ben definiti in cui lo stato del processo è ben noto.

Al contrario, il multithreading presuppone l’esecuzione di più thread nello stesso processo. Ma tutti questi thread condividono lo stesso 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 anche di corromperlo. Allo stesso tempo i punti in cui lo stato del thread è noto per essere sicuri di uccidere un thread completamente dipende dalla logica dell’applicazione e non sono noti né per il sistema operativo né per il linguaggio di programmazione. Di conseguenza terminazione del thread nel momento arbitrario significa ucciderlo in un punto arbitrario del suo percorso di esecuzione e può facilmente portare al danneggiamento dei dati a livello di processo, alla memoria e gestisce perdite, thread leakage e spinlock e altre primitive di sincronizzazione intra-processo lasciate nel stato chiuso che impedisce l’avanzamento di altri thread.

A causa di ciò, l’approccio comune consiste nel forzare gli sviluppatori ad implementare la terminazione sincrona o cooperativa del thread, in cui un thread può richiedere la terminazione del thread e altri thread in punti ben definiti possono controllare questa richiesta e avviare la procedura di spegnimento dallo stato ben definito con il rilascio di tutte le risorse globali del sistema e le risorse locali a livello di processo in modo sicuro e coerente.

Suggerimenti sull’utilizzo della funzione dipendente dal sistema operativo per terminare il thread C ++:

  1. std::thread::native_handle() solo può ottenere il tipo di handle nativo valido del thread prima di chiamare join() o detach() . Dopodiché, native_handle() restituisce 0 – pthread_cancel() eseguirà il coredump.

  2. Per chiamare in modo efficace la funzione di terminazione del thread nativo (ad esempio pthread_cancel) , è necessario salvare l’handle nativo prima di chiamare std::thread::join() o std::thread::detach() . In modo che il tuo terminatore nativo abbia sempre un handle nativo valido da utilizzare.

Per ulteriori spiegazioni, consultare: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .