Russian Qt Forum

Qt => Общие вопросы => Тема начата: serg_hd от Апрель 21, 2010, 21:27



Название: [решено] Ещё раз об остановке потока
Отправлено: serg_hd от Апрель 21, 2010, 21:27
Не могу корректно завершить выполнение потока.
Метод run() класса-наследника QThread:
Код
C++ (Qt)
void myClass::run()
{
 while(true)
{
 this->thread()->wait(50);
 if (!this->suspendFlag)
 {
  qDebug() << rand();
 }
}
}
 
т.е. цикл в нём бесконечный и с помощью suspendFlag контролируется выполнение действий. Проблема в том, что при завершении работы программы имею "QThread: Destroyed while thread is still running".

Деструктор этого класса
Код
C++ (Qt)
myClass::~myClass()
{
qDebug() << this->currentThread()->isRunning();
this->thread()->quit();
qDebug() << this->currentThread()->isRunning();
}
 
показывает всегда
Код
C++ (Qt)
true
true
 
Вместо quit() пробовал кучу других вариантов (ставить wait() перед ним тоже - плюс к тому предупреждению дополнительно выдаёт "QThread::wait: Thread tried to wait on itself"), эффекта 0.
Есть ли ещё варианты?


Название: Re: Ещё раз об остановке потока
Отправлено: niXman от Апрель 21, 2010, 21:28
это нужно еще уметь так извращаться ;D


Название: Re: Ещё раз об остановке потока
Отправлено: serg_hd от Апрель 21, 2010, 21:31
это нужно еще уметь так извращаться ;D
как "так"? Я вообще многое умею ;)


Название: Re: Ещё раз об остановке потока
Отправлено: niXman от Апрель 21, 2010, 21:34
Код
C++ (Qt)
bool running = true;
...
void myClass::run()
{
 while(running)
{
 this->thread()->wait(50);
 if (!this->suspendFlag)
 {
  qDebug() << rand();
 }
}
}
 

где только этот вопрос не поднимался. сколько сотен тем было создано...
и везде один и тот же ответ - единственно правильный способ завершения потока, это вернуться из него.


Название: Re: Ещё раз об остановке потока
Отправлено: niXman от Апрель 21, 2010, 21:38
Цитировать
и везде один и тот же ответ - единственно правильный способ завершения потока, это вернуться из него.
еще нужно понимать, что такое поток. и знать, что это "system dependent".


Название: Re: Ещё раз об остановке потока
Отправлено: serg_hd от Апрель 21, 2010, 21:57
Пересмотрел тут тем 6 с этой же проблемой, но такого решения (завершать его исключительно возвратом) не было, так что спс
Изменил деструктор на:
Код
C++ (Qt)
ThreadManager::~ThreadManager()
{
this->threadIsRunning = false;
this->wait(50);
}
 
пошло


Название: Re: Ещё раз об остановке потока
Отправлено: Igors от Апрель 21, 2010, 21:59
Код
C++ (Qt)
void myClass::run()
{
 while (!mStop)
{
  ....
 }
}
 
inline void MyClass::SetStop( void ) { mStop = true; }
 

Вызывающий
Код
C++ (Qt)
// запускаем
MyClass * theThread = new MyClass();
theThread->start();
 
...
// работаем
...
 
// убиваем нитку
theThread->SetStop();    // даем ей выйти из run()
theThread->wait();       // ждем пока выйдет
delete theThread;        // теперь можно мочить
 


Название: Re: Ещё раз об остановке потока
Отправлено: alexman от Апрель 22, 2010, 08:40
Код
C++ (Qt)
void myClass::run()
{
 while (!mStop)
{
  ....
 }
}
 
inline void MyClass::SetStop( void ) { mStop = true; }
 

Вызывающий
Код
C++ (Qt)
// запускаем
MyClass * theThread = new MyClass();
theThread->start();
 
...
// работаем
...
 
// убиваем нитку
theThread->SetStop();    // даем ей выйти из run()
theThread->wait();       // ждем пока выйдет
delete theThread;        // теперь можно мочить
 

mStop не нужно мьютексом "закрыть"?


Название: Re: [решено] Ещё раз об остановке потока
Отправлено: niXman от Апрель 22, 2010, 08:50
Цитировать
mStop не нужно мьютексом "закрыть"?
нет. с однобайтовыми переменными, операции атомарны. по крайней мере на известных мне аппаратных архитектурах.


Название: Re: [решено] Ещё раз об остановке потока
Отправлено: alexman от Апрель 22, 2010, 08:52
спс, понял!


Название: Re: Ещё раз об остановке потока
Отправлено: ieroglif от Апрель 22, 2010, 10:32
Код
C++ (Qt)
void myClass::run()
{
 while (!mStop)
{
  ....
 }
}
 
inline void MyClass::SetStop( void ) { mStop = true; }
 

Вызывающий
Код
C++ (Qt)
// запускаем
MyClass * theThread = new MyClass();
theThread->start();
 
...
// работаем
...
 
// убиваем нитку
theThread->SetStop();    // даем ей выйти из run()
theThread->wait();       // ждем пока выйдет
delete theThread;        // теперь можно мочить
 

эээ.. а не лучше ли ?
Код
C++ (Qt)
// убиваем нитку
theThread->SetStop();     // даем ей выйти из run()
theThread->deleteLater(); // пусть сам сдохнет как сочтёт нужным
 


Название: Re: Ещё раз об остановке потока
Отправлено: BRE от Апрель 22, 2010, 10:42
эээ.. а не лучше ли ?
Код
C++ (Qt)
// убиваем нитку
theThread->SetStop();     // даем ей выйти из run()
theThread->deleteLater(); // пусть сам сдохнет как сочтёт нужным
 
Момент, когда объект theThread будет разрушен от него самого не зависит и легко может случиться так, что он будет разрушаться при работающей нитке. Поэтому, желательно использовать wait.

Либо использовать сигнал finished:
connect( theThread, SIGNAL( finished() ), theThread, SLOT( deleteLater() ) );