У меня такая же проблема, как у Dibo. Я запускаю длинный цикл вычисления внутри моей функции doWork()
и должен иметь возможность остановить ее из основного потока.
Ответы Чадика Робберта не помогли мне. Первое предложение вел себя так же, как то, что он описывает для функций-членов. То есть, хотя мы используем сигналы и слоты, вызывая setTerminationFlag
слот из сигнала, испускаемого в основном потоке, правильно подключенного к нему, только запускается после окончания цикла. Но, возможно, я сделал что-то не так с реализацией. Если это действительно должно работать, сообщите мне, потому что это похоже на разблокировку сделки.
Его вторая альтернатива использования QThread::currentThread()->isInterruptionRequested()
, чтобы остановить поток, прекратит работу, если бы не тот факт, что вы не можете сбросить этот флаг, если вы планируете повторно использовать поток и рабочий для некоторого аналогичного цикла интенсивной обработки , если не то же самое. Конечно, вы можете сделать это, остановив и запустив нить, но я не уверен, что это не будет иметь побочных эффектов, таких как очистка очередей выполнения. Этот вопрос был фактически размещен как bug report и Тиаго Macieira (ключ для разработчиков Qt) упоминает там, если я процитирую его:
Целью функции requestInterruption является, чтобы закончить нить.
Что делает requestInterruption
неадекватным для работы, так как он сбрасывается только при запуске и окончании резьбы.
Решение, которое я нашел, что не кажется, что чистый для меня, чтобы включить QCoreApplication
в классе рабочих и вызвать QCoreApplicaton::processEvents()
время от времени, чтобы обработать эти поставленные в очередь сигналы в первом предложении Chadick Robbert или обновить класс класса осведомленности о переменных флага, разделяемых между потоками.
Поскольку вызова QCoreApplicaton::processEvents()
внутри вашего цикла может замедлить его резко, что я делаю что-то вроде:
for(unsigned long int i=0; i<800000000 && !*stop; i++){
f += (double)i * .001; // dummy calculation
if(i%10000000 == 0) // Call it only from time to time
QCoreApplication::processEvents(); // update *stop according to main Thread
}
Как вы можете видеть, с этим решением петля сломается только при целых кратных «10000000», которые могут не должны быть адекватными для некоторых случаев использования.
Если кто-нибудь знает об убийственном решении, которое я хотел бы услышать.
Да, я знаю это, но это не проблема. Что делать, если мой цикл «вечно». Я хотел бы остановить его с помощью somethig: for (int i = 0; i <10; ++ i) { if (<конец завершено>) return; сон (1); испускать ping (i); } – Dibo
Флаг имеет наибольший смысл.'while (stillDoingWork && notStopped)' – Anthony
Установлен ли флаг для рабочего из основного потока (например, из кнопки clik) потокобезопасным? Только основной поток пишите на этот флаг, рабочий будет читать только – Dibo