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得られないため、永遠にループすることです。私は何を取りこぼしたか ?どんな助けでもありがたいです。falseMyThread::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()メソッドがブロックされており、イベントループに入ることがないため、スロットstopWatchingThreadが呼び出されることはありません。run()の回転ループによってイベントループをブロックしないように、exec()を呼び出す必要があります。それか、シグナル/スロット接続を使用する代わりに、ウォッチャースレッドにstopWatchingThreadを直接呼び出させます。私は後者に行きます。その場合、keepRunningは複数のスレッドからアクセスされるため、QMutex、QReadWriteLock、またはQAtomicを使用して保護する必要があります。(QMutexから始めてください。最も簡単です)。

于 2013-01-23T09:45:58.027 に答える
0

たぶん、C++コンパイラはでの読み取り操作を最適化しますKeep_running。として宣言してみてくださいvolatile。これは、この変数が「予期せずに」変更される可能性があることをコンパイラに通知します。たとえば、他のスレッドやハードウェア割り込みからです。

于 2013-01-23T08:47:28.120 に答える
0

スレッドでイベントループを使用する場合は、quit()シグナルをスレッドオブジェクトに送信するだけです。

于 2013-01-23T08:42:58.257 に答える