使用QWaitCondition唤醒线程

时间:2013-12-11 15:03:25

标签: multithreading qt mutex

我的Qt应用程序有一个工作线程,可以在可用时处理新数据。到目前为止,工作线程使用QWaitCondition在新数据可用时唤醒。

但是,仅当线程通过wait()主动等待时才会触发QWaitCondition。虽然新数据在线程仍在工作时可用,或者在它运行到下一个wait()命令之前可能会发生。

我正在寻找MFC中的CEvent之类的东西,它可以随时“记住”新数据通知,并且如果自上次wait()调用以来已经发出新数据信号,则不会等待。在Qt中实现这一目标的最佳方法是什么?

谢谢, 费边

2 个答案:

答案 0 :(得分:2)

如果某个其他线程可以在新数据进入时触发信号,您可以实现一个简单的调度程序类来在适当的时候唤醒您的线程(使用@ratchet怪建议的信号/插槽):

class Data;
class Scheduler : public QObject
{
Q_OBJECT
public:

Scheduler(QTread* workerIn) : worker(workerIn) {};

Q_SLOT void OnNewData(Data* data)
{
QMutexLocker lock(&mutex);
while(worker->isRunning())
   condition.wait(&mutex);

Q_EMIT startWorker(data);
}; 

Q_SLOT void OnThreadFinished() 
{
     condition.wakeOne();
}

Q_SIGNAL void startWorker(Data* data);    

private:
QThread* worker;
QWaitCondition condition;
QMutex mutex;
};

如果在工作程序运行时有多个数据值,则qt事件队列将正确排队。调度程序必须存在于自己的线程中。信号startWorker必须连接到工作线程中的正确插槽,工作线程的完成插槽必须连接到OnThreadFinished()插槽。

答案 1 :(得分:1)

QWaitCondition应与QMutex一起使用

public void Worker::add(Data data)
{
    QMutexLocker lock(&mutex);
    //add data
    condition.wakeOne();
}


public void Worker::run()
{
    while(true)
    {
        Data data;
        {
            // no other thread will be able to trigger a wake while inside this block
            QMutexLocker lock(&mutex);
            if(shouldStop)return;
            while(!hasAvailable()) 
                condition.wait(&mutex);
            data = removeOne();
        }
        //do something with data;

    }
}

这样一来,如果一个新的数据包出现在线程中wait并且wakeOne将不会被检查时间和等待调用之间的另一个线程触发

更好的选择是使用信号和插槽