QThreads может зайти в тупик, если они заканчиваются «естественно» во время завершения.
Например, в Unix, если поток ожидает «чтение», попытка завершения (сигнал Unix) заставит «читать» вызов прерываться с кодом ошибки до уничтожения потока.
Это означает, что нить все еще может достигать естественной точки выхода при ее окончании. Когда это происходит, достигается взаимоблокировка, поскольку некоторые внутренние мьютекс уже заблокированы вызовом «завершить».
Мое обходное решение - убедиться, что нить никогда не возвращается, если она была прекращена.
while(read(...) > 0) {
// Do stuff...
}
while(wasTerminated)
sleep(1);
return;
wasTerminated здесь на самом деле реализован немного более сложным, с использованием атомных Интсов:
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 добавить более общий "Qt" тег. – ChrisV
Qt doc говорит: «Предупреждение: эта функция опасна и ее использование не рекомендуется. Поток может быть завершен в любой точке его кодового пути. Потоки могут быть прерваны при изменении данных. Нет возможности для очистки потока после сам, разблокировать любые удерживаемые мьютексы и т. д. Короче говоря, используйте эту функцию только в случае крайней необходимости. Прекращение может быть явно включено или отключено, вызвав QThread :: setTerminationEnabled(). Вызов этой функции при отключении прерывания приводит к отсрочке завершения, пока окончание не будет включено ». –