Eventuali duplicati:
C++0x thread interruptionVoglio uccidere uno std :: thread usando il suo oggetto thread?
sto cercando di uccidere/fermare un C++ std :: thread utilizzando il suo oggetto thread.
Come possiamo fare questo?
Eventuali duplicati:
C++0x thread interruptionVoglio uccidere uno std :: thread usando il suo oggetto thread?
sto cercando di uccidere/fermare un C++ std :: thread utilizzando il suo oggetto thread.
Come possiamo fare questo?
Non è possibile.
std::threads
non sono interrompibili. È possibile utilizzare boost::thread
che offre questa funzionalità.
Boost esegue questa operazione definendo i "punti di interruzione" su cui terminerà il thread se viene interrotto e raggiunge tale punto.
Tuttavia, il più delle volte pensare a una riprogettazione potrebbe essere il modo più semplice e pulito per raggiungere ciò che si sta cercando di ottenere.
Se si sta ancora cercando un'implementazione di thread interrompibili in C++ 11, Anthony Williams (proprietario del thread di boost) prenota "C++ Concurrency in Action". Egli passa attraverso una implementazione di base di come una cosa del genere può essere raggiunta.
std::thread::native_handle
consente di accedere alla maniglia di thread sottostante specifica della piattaforma che potrebbe supportare l'interruzione, tuttavia questo approccio rende il codice non modificabile e probabilmente non più pulito in alcun modo.
@ la risposta di bamboon è buona, tuttavia ritengo che questo meriti una dichiarazione più forte.
Qualunque sia la lingua che usi, il tuo programma acquisirà e rilascerà risorse: memoria, descrittori di file, ... Per i programmi semplici che vengono sparati in un colpo, la perdita di risorse non conta molto: quando il programma termina automaticamente i sistemi operativi moderni riprendere le risorse; tuttavia, per i programmi di lunga durata un requisito fondamentale non è quello di perdere risorse, o almeno non ripetitivamente.
Pertanto, è necessario è stato insegnato fin dall'inizio che quando si acquista una risorsa si dovrà assicurarsi che sia rilasciato a un certo punto:
void foo(int i) {
int* array = malloc(sizeof(int) * i);
/* do something */
free(array);
}
Quindi, porsi la domanda:
Beh, come abbiamo detto, quando un programma termina il sistema operativo raccoglie le risorse indietro, in modo da assumere (e questo è un po 'ipotesi) che non hai acquisire una risorsa un altro sistema O che questo sistema va bene protetto da tale abuso, nessun danno, nessun fallo.
Tuttavia, quando si uccide un thread, il programma viene comunque eseguito, quindi il sistema operativo non raccoglie le risorse. Di memoria trapelata, hai bloccato un file per la scrittura che non puoi più sbloccare, ... Non devi uccidere i thread.
I linguaggi di livello superiore hanno un modo per gestire questo: eccezioni. Poiché i programmi dovrebbero essere comunque sicuri delle eccezioni, Java (ad esempio) ucciderà un thread mettendolo in pausa, generando un'eccezione nel punto di esecuzione e rilassando delicatamente lo stack. Tuttavia non esiste ancora una tale funzionalità in C++.
È impossibile? No, ovviamente no. In realtà, si potrebbe perfettamente riutilizzare la stessa idea:
std::thread
, interruptible_thread
classe conterrà anche una bandiera interruptstd::thread
al momento del lancio, e conservarla in un filettatura modo localeCioè:
// Synopsis
class interrupt_thread_exception;
class interruptible_thread;
void check_for_interrupt();
// Interrupt exception
class interrupt_thread_exception: public virtual std::exception {
public:
virtual char const* what() const override { return "interrupt"; }
}; // class interrupt_thread_exception
// Interruptible thread
class interruptible_thread {
public:
friend void check_for_interrupt();
template <typename Function, typename... Args>
interruptible_thread(Function&& fun, Args&&... args):
_thread([](std::atomic_bool& f, Function&& fun, Args&&... args) {
_flag_ref = &f; fun(std::forward<Args>(args)...);
},
_flag,
std::forward<Function>(fun),
std::forward<Args>(args)...)
{}
bool stopping() const { return _flag.load(); }
void stop() { _flag.store(true); }
private:
static thread_local std::atomic_bool* _flag_ref = nullptr;
std::atomic_bool _flag = false;
std::thread _thread;
}; // class interruptible_thread
// Interruption checker
inline void check_for_interrupt() noexcept(false) {
if (not interruptible_thread::_flag_ref) { return; }
if (not interruptible_thread::_flag_ref->load()) { return; }
throw interrupt_thread_exception();
} // check_for_interrupt
Ora è possibile semplicemente cospargere il codice filettato con controlli per l'interruzione nelle posizioni appropriate.
+1, ** questo ** è un concetto così importante. I thread sono in un diverso dominio di risorse e sicurezza per i processi. Richiedono un approccio cooperativo piuttosto che "contraddittorio". Riforma il codice in modo che i thread possano terminare correttamente quando richiesto. –
'void foo (int)' non è già sicuro, se hai un controllo di interruzione nel mezzo di '/ * fai qualcosa */'sarà ancora sbagliato. –
Quale segnale? Stai parlando di generare un'eccezione durante l'interruzione e alcune piattaforme fanno lo stesso per pthread_cancel. Se viene lanciata un'eccezione, la funzione non viene completata. –
Correlato: http://stackoverflow.com/questions/2790346/c0x-thread-interruption – zch