QThreads może zakleszczać się, jeśli zakończy się "naturalnie" podczas zakończenia.
Na przykład w systemie Unix, jeśli wątek oczekuje na wywołanie "przeczytane", próba zakończenia (sygnał uniksowy) spowoduje przerwanie wywołania "odczytu" z kodem błędu, zanim wątek zostanie zniszczony.
Oznacza to, że wątek może nadal osiągać swój naturalny punkt wyjścia podczas kończenia. Gdy to zrobi, zostanie osiągnięty zakleszczenie, ponieważ niektóre wewnętrzne muteksy są już zablokowane przez wywołanie "zakończ".
Moje obejście polega na upewnieniu się, że wątek nigdy nie zostanie zwrócony, jeśli został zakończony.
while(read(...) > 0) {
// Do stuff...
}
while(wasTerminated)
sleep(1);
return;
wasTerminated tutaj jest faktycznie realizowany nieco bardziej złożone, stosując ints atomów:
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);
}
}
Retagged dodać więcej wspólnego "qt" tag. – ChrisV
Dokument Qt mówi: "Ostrzeżenie: ta funkcja jest niebezpieczna, a jej użycie jest odradzane." Wątek może zostać zakończony w dowolnym punkcie ścieżki kodu, wątki mogą zostać przerwane podczas modyfikowania danych. Nie ma szans na wyczyszczenie wątku po samodzielnie, odblokuj dowolne zawieszone muteksy itp. Krótko mówiąc, użyj tej funkcji tylko, jeśli jest to absolutnie konieczne, Zakończenie można jawnie włączyć lub wyłączyć, wywołując QThread :: setTerminationEnabled(). Wywołanie tej funkcji, gdy zakończenie jest wyłączone powoduje odłożenie zakończenia, do momentu zakończenia połączenia. " –