我正在尝试创建一个线程(HttpWorker),当需要唤醒并发送http请求时。我希望这可以在一个线程中完成。我正在使用Qt实现。
我认为我会这样做的方法是拥有一个类MyHttpWorker,将其移动到另一个线程,连接插槽/信号等。然后在线程启动时,我将使用QNetworkAccessManager
来调用get请求。我会在请求发送后使用QWaitCondition
暂停线程,每当我需要发送另一个时,我都会恢复该线程。
但是,当我暂停httpworker线程时,根本不会调用FinishedSlot。如果我使用该类简单地调用一个http请求,它执行没有问题。所以问题与QWaitCondition
有关(或者只是冻结线程)。
我可以简单地为每个请求创建和销毁一个工作线程和线程,但是我需要发送大量的http请求,所以我认为这种方法过于消耗(创建线程并一遍又一遍地销毁它们)。
我感谢任何帮助。
这是我的代码:
MyHttpWorker.h
#include <QNetworkReply>
#include <QDebug>
#include <QObject>
#include <QNetworkAccessManager>
#include <QThread>
#include <QWaitCondition>
#include <QMutex>
class MyHttpWorker : public QObject
{
Q_OBJECT
QNetworkAccessManager* nam;
QMutex syncPause;
QWaitCondition pauseCond;
public:
explicit MyHttpWorker(QObject *parent = 0);
void MyWake();
public slots:
void SetTheThread(QThread* thread);
void MyStart();
void finishedSlot(QNetworkReply* reply);
};
MyHttpWorker.cpp
MyHttpWorker::MyHttpWorker(QObject *parent) :
QObject(parent)
{
nam = new QNetworkAccessManager(this);
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
}
void MyHttpWorker::finishedSlot(QNetworkReply* reply)
{
qDebug() << "Finished"; //This slot is never even reached, when i used QWaitCond...
if (reply->error() == QNetworkReply::NoError)
{
QByteArray bytes = reply->readAll();
QString string(bytes);
qDebug() << string;
}else
{
qDebug() << reply->errorString();
}
reply->deleteLater();
}
void MyHttpWorker::SetTheThread(QThread* thread){
QObject::connect(thread,SIGNAL(started()),this,SLOT(MyStart()));
}
void MyHttpWorker::MyWake(){
pauseCond.wakeAll();
}
void MyHttpWorker::MyStart(){
qDebug() << "Start" ;
while(true){
syncPause.lock();
qDebug() << "thread waiting...";
pauseCond.wait(&syncPause);
qDebug() << "thread resumed.";
syncPause.unlock();
//sending the actual request here
QNetworkRequest myRequest;
myRequest.setUrl(QUrl("http://www.google.com"));
nam->get(myRequest);
}
}
的main.cpp
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <myhttpworker.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//create the worker, thread and launch it... (worker is waiting by default)
MyHttpWorker* worker = new MyHttpWorker;
QThread* httpThread = new QThread;
worker->SetTheThread(httpThread);
worker->moveToThread(httpThread);
httpThread->start();
//try and send 5 requests ...
for(int i=0;i<5;i++){
qDebug() << "Unpausing";
QThread::currentThread()->msleep(1000);
worker->MyWake();
}
return a.exec();
}
答案 0 :(得分:2)
不要创建无限循环,而是让偶数循环处理它:
void MyHttpWorker::MyWake()
{
QMetaObject::invokeMethod(this,"doSend");
//send to the event loop
}
// new slot
void MyHttpWorker::doSend(){
//sending the actual request here
QNetworkRequest myRequest;
myRequest.setUrl(QUrl("http://www.google.com"));
nam->get(myRequest);
}
//and remove the myStart and all that synchronisation
然后当你想要停止它时,只需向线程发送一个quit
。我建议你也将帖子的finished
信号连接到deleteLater
的{{1}}位置