我的Qt应用程序有一个工作线程,可以在可用时处理新数据。到目前为止,工作线程使用QWaitCondition在新数据可用时唤醒。
但是,仅当线程通过wait()主动等待时才会触发QWaitCondition。虽然新数据在线程仍在工作时可用,或者在它运行到下一个wait()命令之前可能会发生。
我正在寻找MFC中的CEvent之类的东西,它可以随时“记住”新数据通知,并且如果自上次wait()调用以来已经发出新数据信号,则不会等待。在Qt中实现这一目标的最佳方法是什么?
谢谢, 费边
答案 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
将不会被检查时间和等待调用之间的另一个线程触发
更好的选择是使用信号和插槽