QThreads può deadlock se terminano "naturalmente" durante la terminazione.
Ad esempio in Unix, se il thread è in attesa di una chiamata "read", il tentativo di terminazione (un segnale Unix) farà interrompere la chiamata "read" con un codice di errore prima che il thread venga distrutto.
Ciò significa che il thread può ancora raggiungere il punto di uscita naturale mentre viene terminato. Quando lo fa, viene raggiunto un deadlock poiché un mutex interno è già bloccato dalla chiamata "terminate".
Per risolvere il problema, verificare che il thread non sia mai restituito se è stato terminato.
while(read(...) > 0) {
// Do stuff...
}
while(wasTerminated)
sleep(1);
return;
wasTerminated qui è in realtà implementato un po 'più complesso, utilizzando int atomiche:
enum {
Running, Terminating, Quitting
};
QAtomicInt _state; // Initialized to Running
void myTerminate()
{
if(_state.testAndSetAquire(Running, Terminating))
terminate();
}
void run()
{
[...]
while(read(...) > 0) {
[...]
}
if(!_state.testAndSetAquire(Running, Quitting)) {
for(;;) sleep(1);
}
}
rimarcato aggiungere il nome più comune "qt". – ChrisV
Il doc Qt dice: "Attenzione: questa funzione è pericolosa e il suo utilizzo è sconsigliato Il thread può essere terminato in qualsiasi punto del suo percorso di codice.I thread possono essere terminati durante la modifica dei dati.Non c'è possibilità per il thread di ripulire dopo in sé, sblocca qualsiasi mutex trattenuto, ecc. In breve, usa questa funzione solo se assolutamente necessario. La terminazione può essere abilitata o disabilitata in modo esplicito chiamando QThread :: setTerminationEnabled(). Chiamando questa funzione mentre la terminazione è disabilitata, la terminazione viene differita, fino alla riattivazione della terminazione. " –