2011-07-15 134 views
7

如何在睡眠時喚醒QThread?喚醒處於睡眠狀態的QThread?

我有一個線程在後臺運行,然後現在醒來,做一些小東西,但是如果我想以受控方式停止線程,我必須等待他醒來爲了讓他離開自我。而且由於他睡得很久,這可能會很煩人。

下面是一個顯示基本問題的小例子代碼。

讓我們從這個例子中睡覺5秒鐘然後打印一個點開始。

#include <QDebug> 
#include "TestThread.h" 

void TestThread::run() 
{ 
    running = true; 
    while(running == true) 
    { 
     qDebug() << "."; 
     QThread::sleep(5); 
    } 
    qDebug() << "Exit"; 
} 

void TestThread::stop() 
{ 
    running = false; 
} 

然後我們有主啓動線程然後殺死他。

#include <QDebug> 
#include "TestThread.h" 

int main(int argc, char *argv[]) 
{ 
    qDebug() << "Start test:"; 
    TestThread *tt = new TestThread(); 

    tt->start(); 
    sleep(2); 
    tt->stop(); 
    tt->wait(); 

    delete tt;  
} 

問題是,tt-> wait();必須等待線程正在睡眠的5秒鐘。 我可以稱之爲「從睡眠中醒來」,這樣他就可以繼續。

或者是否有更好的方法來做到這一點?

/感謝


更新我得到了它與QMutex和工作的tryLock:

#include <QDebug> 
#include "TestThread.h" 

QMutex sleepMutex; 

void TestThread::run() 
{ 
    qDebug() << "Begin"; 
    //1. Start to lock 
    sleepMutex.lock(); 
    //2. Then since it is locked, we can't lock it again 
    // so we timeout now and then. 
    while(!sleepMutex.tryLock(5000)) 
    { 
     qDebug() << "."; 
    } 
    //4. And then we cleanup and unlock the lock from tryLock. 
    sleepMutex.unlock(); 
    qDebug() << "Exit"; 
} 

void TestThread::stop() 
{ 
    //3. Then we unlock and allow the tryLock 
    // to lock it and doing so return true to the while 
    // so it stops. 
    sleepMutex.unlock(); 
} 

但它會更好地使用QWaitCondition?還是一樣?


更新:本QMutex休息,如果它不是啓動和停止他同樣的花紋, 所以這裏是QWaitCondition一試。

#include <QDebug> 
#include <QWaitCondition> 
#include "TestThread.h" 

QMutex sleepMutex; 

void TestThread::run() 
{ 
    qDebug() << "Begin"; 

    running = true; 
    sleepMutex.lock(); 
    while(!waitcondition.wait(&sleepMutex, 5000) && running == true) 
    { 
     qDebug() << "."; 
    } 
    qDebug() << "Exit"; 
} 

void TestThread::stop() 
{ 
    running = false; 
    waitcondition.wakeAll(); 
} 

回答

6

你可以使用一個QWaitCondition,而不是一個簡單的sleep。如果給你更多的控制。

用法示例這裏:Wait Conditions Example

+0

聽起來不錯,但你是怎麼說的? – Johan

+0

看看我鏈接的例子。這個想法是鎖定一個互斥鎖並使用一個等待條件的'wait(QMutex *,long)'函數來代替你的睡眠,並在'stop()'函數中使用'wakeAll()'或'wakeOne()'。你的編輯不好:你不應該在同一個互斥體對象上調用一個線程的'lock()'和另一個線程的'unlock()'。 – Mat

+0

所以你永遠不解鎖他?你保持「布爾運行」,所以停止循環? – Johan

1

我不認爲一個便攜的解決方案存在(儘管可能有一些操作系統的一些設施,如POSIX信號)。無論如何,QT本身不提供這樣的手段,因此,你可以模擬像

void TestThread::run() 
{ 
    running = true; 
    while(running == true) 
    { 
     qDebug() << "."; 
     // Quantize the sleep: 
     for (int i = 0; i < 5 && running; ++i) QThread::sleep(1); 
    } 
    qDebug() << "Exit"; 
} 

但最好的解決辦法仍然是一個QWaitCondition,通過墊指出。