[英]Why is my thread which is waiting on a QWaitCondition not returning
我有数据结构,我想等到它重新获取数据。 当我调用setInterrupt时,我希望我的线程停止但它永远不会返回。
这是我的队列:
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();
}
这是我的消费者主题:
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();
}
我得到以下输出:
好像我在BufferedIpQqueue :: get()方法中的while(queue.isEmpty())库存。 为什么我的方法没有返回到IpCheckWorker :: process()?
如何正确地做任何帮助都会非常友好。
你正在做的是重新实现一个稍微不那么灵活的QThreadPool
。 如果您愿意,可以查看其实现方式 ,了解它如何使用等待条件。 我只是建议使用QThreadPool
并将其称为一天,因为它非常适合您的要求。
线程池维护QRunnable
实例的队列。 实例由空闲线程拾取。 线程管理是自动的。 QRunnable
是一个类似于QEvent
的轻量级类 - 它不是QObject
。
QThreadPool
不是单身人士。 有一个全局实例,但您不必使用它。 您可以拥有自己的实例。
此示例与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.