[英]Why is my thread which is waiting on a QWaitCondition not returning
I have data structure where I want to wait until it recives data. 我有数据结构,我想等到它重新获取数据。 When I call setInterrupt I want my thread to stop but it never returns. 当我调用setInterrupt时,我希望我的线程停止但它永远不会返回。
This is my queue: 这是我的队列:
BufferedIpQqueue::BufferedIpQqueue()
{
}
BufferedIpQqueue::~BufferedIpQqueue()
{
bufferWaitCondition.wakeAll();
}
QString BufferedIpQqueue::get()
{
QMutexLocker locker(&mutex);
while(queue.isEmpty())
{
qDebug() << "waiting at mutex " << &mutex << "calling threadid: " << QThread::currentThreadId();
bufferWaitCondition.wait(&mutex);
}
return queue.first();
}
void BufferedIpQqueue::put(QString &data)
{
QMutexLocker locker(&mutex);
queue.append(data);
bufferWaitCondition.wakeAll();
}
void BufferedIpQqueue::wakAllThreads()
{
qDebug() << "wake all waiting threads at mutex: " << &mutex << "calling threadid: " << QThread::currentThreadId();
bufferWaitCondition.wakeAll();
}
This is my consumer thread: 这是我的消费者主题:
IpCheckWorker::IpCheckWorker(BufferedIpQqueue *queue)
{
this->queue = queue;
interrupt = false;
}
void IpCheckWorker::setInterrupt(bool value)
{
QMutexLocker lock(&mutex);
qDebug() << "wake all threads";
interrupt = value;
queue->wakAllThreads();
}
bool IpCheckWorker::getInterruptFlag()
{
QMutexLocker lock(&mutex);
return interrupt;
}
void IpCheckWorker::process()
{
while(getInterruptFlag() == false)
{
qDebug() << "enter process loop ThreadID:" << QThread::currentThreadId();
QString check_ip = queue->get();
qDebug() << "proccess ThreadID:" << QThread::currentThreadId();
}
qDebug() << "leave process event ThreadID:" << QThread::currentThreadId();
emit finished();
}
I get the following output: 我得到以下输出:
It seems like I am stock at while(queue.isEmpty()) in my BufferedIpQqueue::get() method. 好像我在BufferedIpQqueue :: get()方法中的while(queue.isEmpty())库存。 Why is my mthod not returning to IpCheckWorker::process()? 为什么我的方法没有返回到IpCheckWorker :: process()?
Any help how to do it right would be very kind. 如何正确地做任何帮助都会非常友好。
What you are doing is reimplementing a slightly less flexible QThreadPool
. 你正在做的是重新实现一个稍微不那么灵活的QThreadPool
。 If you wish, you can look in its implementation for how it uses the wait conditions. 如果您愿意,可以查看其实现方式 ,了解它如何使用等待条件。 I'd simply advise to use QThreadPool
and call it a day, since it's a perfect fit for your requirements. 我只是建议使用QThreadPool
并将其称为一天,因为它非常适合您的要求。
The thread pool maintains a queue of QRunnable
instances. 线程池维护QRunnable
实例的队列。 The instances are picked up by idle threads. 实例由空闲线程拾取。 The thread management is automatic. 线程管理是自动的。 QRunnable
is a lightweight class similar to QEvent
- it is not a QObject
. QRunnable
是一个类似于QEvent
的轻量级类 - 它不是QObject
。
QThreadPool
is not a singleton. QThreadPool
不是单身人士。 There is a global instance, but you don't have to use it. 有一个全局实例,但您不必使用它。 You can have your own instance. 您可以拥有自己的实例。
This example is compatible with Qt 4.4 & up. 此示例与Qt 4.4及更高版本兼容。
#include <QCoreApplication>
#include <QThreadPool>
#include <QRunnable>
#include <QBasicTimer>
#include <QDebug>
#include <cstdlib>
class Thread : public QThread {
public:
using QThread::msleep;
};
class IpData {
QString m_value;
public:
IpData(const QString & str) : m_value(str) {}
const QString & value() const { return m_value; }
};
class IpRunnable : public QRunnable, IpData {
void run() {
qDebug() << "[" << QThread::currentThreadId()
<< "] processing ip" << value();
Thread::msleep(qrand() < (RAND_MAX/4.0) ? 0 : 100);
}
public:
IpRunnable(const IpData & data) : IpData(data) {}
IpRunnable(const QString & str) : IpData(str) {}
};
class Test : public QObject {
Q_OBJECT
int i;
QBasicTimer timer;
void timerEvent(QTimerEvent * t) {
if (t->timerId() != timer.timerId()) return;
QThreadPool::globalInstance()->start(new IpRunnable(QString::number(i)));
if (++i > 100) qApp->quit();
}
public:
Test() : i(0) { timer.start(20, this); }
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QThreadPool::globalInstance()->setMaxThreadCount(5);
Test test;
return app.exec();
}
#include "main.moc"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.