2013-01-23 101 views
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從未在MyThread::run()得到false值永遠發出stopWatchingThreadwhile循環。 我錯過了什麼? 任何幫助將不勝感激。

+0

你檢查過,如果你真的進入'MyThread :: stopWatchingThread()'? – sashoalm

+0

是的,我的'Keep_running'是假的 – Oumaya

+0

你確定Keep_Running是同一個變量嗎?從run()和MyThread :: stopWatchingThread()中打印它的地址(使用'qDebug()<<&Keep_Running;')並且比較 – sashoalm

回答

2

不要在Qt中顯式創建線程類。相反,創建一個工作對象,將該對象移動到QThread,然後在QThread上調用start()。這裏有一個簡單的例子:

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。這應該讓你開始。

+0

謝謝你的時間它終於工作: ) – Oumaya

0

如果您在線程中使用事件循環,只需將quit()信號發送給線程對象。

+0

感謝您的回覆,您是什麼意思的事件循環?它是時間塊嗎?在設置'Keep_running'後,我在'stopWatchingThread()'中調用了'quit()',但徒勞無功。 – Oumaya

+0

您可以通過調用'run()'方法調用'QThread :: exec()'來啓動事件循環。請參閱http://doc.qt.digia.com/qt/qthread.html#exec – sashoalm

+0

無限/長時間運行while循環將使事件循環無用。 –

0

也許你的C++編譯器優化了Keep_running上的讀操作。嘗試聲明它爲volatile,它告訴編譯器該變量可能「意外」改變,例如來自其他線程或硬件中斷。

+0

謝謝你的時間,我將它更改爲'volatile',相同的結果:( – Oumaya

1

由於您的run()方法被阻塞且事件循環從未輸入,所以不會調用插槽stopWatchingThread。您必須調用exec()並且不要通過run()中的旋轉循環來阻塞事件循環。或者,或者讓觀察者線程直接調用stopWatchingThread,而不是使用信號/插槽連接。我會選擇後者。 keepRunning將從多個線程訪問,因此您必須使用QMutex,QReadWriteLock或QAtomic來保護它。 (從QMutex開始,這是最簡單的)。