Как я могу завершить QThread

В последнее время я сталкиваюсь с этой проблемой, как я сказал в этом разделе. Я пробовал использовать QThread:: terminate(), но я просто НЕ могу остановить поток, который находится в мертвой петле (скажем, в то время как (1)).

Большое спасибо.

Ответ 1

Прекращение потока - это простое решение для остановки операции async, но обычно это плохая идея: поток может выполнять системный вызов или может быть посреди обновления структуры данных при ее завершении, что может оставьте программу или даже ОС в неустойчивом состоянии.

Попробуйте преобразовать ваше время (1) во время (isAlive()) и make isAlive() вернуть false, когда вы хотите, чтобы поток вышел.

Ответ 2

Вы пробовали exit или quit?

Ответ 3

Вызов потока QThread::setTerminationEnabled(false)? Это приведет к бесконечной задержке потока.

EDIT: я не знаю, на какой платформе вы работаете, но я проверил реализацию Windows QThread:: terminate. Предполагая, что поток фактически запускался для начала, и завершение не было отключено с помощью вышеупомянутой функции, это в основном оболочка вокруг TerminateThread() в Windows API. Эта функция принимает неуважение от нитей и, как правило, оставляет беспорядок с утечками ресурсов и подобным обвисшим состоянием. Если он не убивает поток, вы либо имеете дело с вызовами ядра зомби (скорее всего, заблокированными ввода-выводами), либо даже имеют большие проблемы.

Ответ 4

Чтобы использовать неназванные каналы

int gPipeFdTest[2];  //create a global integer array

Как когда вы собираетесь создавать каналы, используйте

if( pipe(gPipeFdTest) < 0)

{

perror("Pipe failed");

exit(1);

}

В приведенном выше коде будет создан канал, который имеет два конца gPipeFdTest [0] для чтения и gPipeFdTest [1] для записи. Что вы можете сделать, так это в вашей функции запуска, настроенной на чтение канала с использованием системного вызова. И с того места, где вы хотите выйти из режима работы, там настроена запись с использованием системного вызова. Я использовал выбранный системный вызов для мониторинга конца считывания, поскольку он подходит для моего внедрения. Постарайтесь понять все это в вашем случае. Если вам нужна дополнительная помощь, дайте мне шум.

Edit:

Моя проблема была такой же, как твоя. У меня было некоторое время (1) цикл, а другие вещи, которые я пробовал, нуждались в мьютексах и других причудливых многопоточных mumbo jumbo, которые добавили сложности и отладки были кошмаром. Использование труб освободило меня от этих сложностей, кроме упрощенного кода. Я не говорю, что это лучший вариант, но в моем случае это была лучшая и самая чистая альтернатива. Перед этим решением я прослушивал свое приложение.

Ответ 5

QThreads могут заходить в тупик, если они заканчиваются "естественно" во время завершения.

Например, в Unix, если поток ожидает "чтение", попытка завершения (сигнал Unix) заставит "читать" вызов прервать код ошибки до уничтожения потока.

Это означает, что поток может дойти до естественной точки выхода при ее завершении. Когда это происходит, достигается взаимоблокировка, поскольку некоторые внутренние мьютексы уже заблокированы вызовом "завершать".

Мое обходное решение - убедиться, что нить никогда не вернется, если она была прервана.

while( read(...) > 0 ) {

  // Do stuff...
}

while( wasTerminated )
  sleep(1);

return;

wasTerminated здесь фактически реализован немного сложнее, используя атомные ints:

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);
  }
}