1

我想在发出信号时停止循环线程所以这是我的代码

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

所以一切都很顺利,但我的问题是发射后Keep_running永远不会获得false价值,因此永远循环。我错过了什么 ?任何帮助将不胜感激。MyThread::run()stopWatchingThreadwhile

4

4 回答 4

2

不要在 Qt 中显式创建线程类。相反,创建一个工作对象,将该对象移动到,QThread然后调用start(). QThread这是一个简单的例子:

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.
}

我省略了一些标准的 QApplication 样板,但如果你使用 Qt,你已经有了。这应该让你开始。

于 2013-01-23T19:54:27.163 回答
1

由于您的 run() 方法处于阻塞状态并且从未进入事件循环,因此永远不会调用 slot stopWatchingThread。您必须调用 exec() 并且不能通过 run() 中的旋转循环阻塞事件循环。要么,要么让观察者线程直接调用 stopWatchingThread 而不是使用信号/插槽连接。我会选择后者。keepRunning 将被多个线程访问,因此您必须使用 QMutex、QReadWriteLock 或 QAtomic 来保护它。(从 QMutex 开始,这是最简单的)。

于 2013-01-23T09:45:58.027 回答
0

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

于 2013-01-23T08:42:58.257 回答
0

也许您的 C++ 编译器优化了Keep_running. 尝试将其声明为volatile,这会告诉编译器此变量可能会“意外”更改,例如来自其他线程或硬件中断。

于 2013-01-23T08:47:28.120 回答