简体   繁体   English

如何停止循环线程

[英]How to stop looping thread

I want to stop a looping thread when a signal was emitted so here is my code 我想在发出信号时停止循环线程,所以这是我的代码

void  MyThread::stopWatchingThread()
{
    qDebug()<<"MyThread::stopWatchingThread()";    
    Keep_running=false;
    qDebug()<<"MyThread::stopWatchingThread Keep_running"<<Keep_running;
    ...
}

void MyThread::run()
{
  qDebug()<<"MyThread::run()";
  qDebug()<<"MyThread::run Keep_running"<<Keep_running;  
  while(Keep_running)
    {
     ...
     }
  qDebug()<<"MyThread::run Keep_running"<<Keep_running;
  Keep_running=false;
  qDebug()<<"MyThread::run Keep_running"<<Keep_running;
}

void Watcher::Init()
{
    WatchingThread=new MyThread(this->L_RootToWatch);
    connect(this,SIGNAL(stopmonotiring()),WatchingThread, SLOT(stopWatchingThread()));
...
}
void Watcher::StartWatching()
{
    WatchingThread->start();
}

void Watcher::StopWatching()
{
    emit stopmonotiring();        
}

So every thing goes all right but my problem is that Keep_running never get false value in MyThread::run() after emitting stopWatchingThread and so while loop for ever. 所以每件事情都可以,但我的问题是Keep_running在发出stopWatchingThread之后永远不会在MyThread::run()得到false值,所以while循环永远。 What did I miss ? 我错过了什么 ? any help will be appreciated. 任何帮助将不胜感激。

Don't create threaded classes explicitly in Qt. 不要在Qt中显式创建线程类。 Instead, create a worker object, move that object to a QThread , then call start() on the QThread . 相反,创建一个工作对象,将该对象移动到QThread ,然后在QThread上调用start() Here's a quick example: 这是一个简单的例子:

class Worker : public QObject
{
  Q_OBJECT
public:
  Worker( QObject * parent = 0 )
    : QObject( parent )
  {}

public slots:
  void doWork( ... )
  { 
    // do work here
  }

  void stopMonitoring()
  { 
    emit finished();
  }

signals:
  void finished();
};

int main()
{
  Worker * w = new Worker();
  QThread * thread = new QThread();
  QObject::connect( w, SIGNAL(finished()), thread, SLOT(quit())
  QObject::connect( w, SIGNAL(finished()), w, SLOT(deleteLater())
  QObject::connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater())
  w->moveToThread( thread );
  thread->start();

  // some other object emits a signal connected to the 'doWork()' slot.
}

I omitted some of the standard QApplication boiler-plate, but you have that already if you're using Qt. 我省略了一些标准的QApplication样板,但如果你使用的是Qt,你已经有了。 This should get you started. 这应该让你开始。

As your run() method is blocking and the event loop never entered, the slot stopWatchingThread will never be called. 由于您的run()方法阻塞且事件循环从未进入,因此永远不会调用slot stopWatchingThread。 You must call exec() and not block the event loop by a spinning loop in run(). 您必须调用exec(),而不是通过run()中的旋转循环来阻止事件循环。 Either that, or have the watcher thread call stopWatchingThread directly instead of using a signal/slot connection. 要么是这样,要么让观察者线程直接调用stopWatchingThread而不是使用信号/插槽连接。 I'd go for the latter. 我会选择后者。 keepRunning will be accessed from multiple threads then, so you have to protect it using a QMutex, QReadWriteLock or QAtomic. keepRunning将从多个线程访问,因此您必须使用QMutex,QReadWriteLock或QAtomic保护它。 (Start with QMutex, it's easiest). (从QMutex开始,这是最简单的)。

如果在线程中使用事件循环,只需将quit()信号发布到线程对象。

Maybe your C++ compiler optimizes away the read operation on Keep_running . 也许你的C ++编译器优化了Keep_running上的读操作。 Try declaring it as volatile , which tells the compiler that this variable might change "unexpectedly", eg from other threads or hardware interrupts. 尝试将其声明为volatile ,它告诉编译器此变量可能会“意外地”更改,例如来自其他线程或硬件中断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM