【发布时间】:2015-03-19 07:05:28
【问题描述】:
我在使用QThreads 时遇到了一些问题,这让我在找到合适的组合之前探索了不同的组合。但是,在涉及事件循环和信号槽处理时,我仍然不完全理解在下面显示的四种情况下到底发生了什么。
我在 OUTPUT 部分添加了一些 cmets,但正如您所见,我不确定我对导致观察到的行为的假设是否正确。另外我不确定case 3 是否可以在实际代码中使用。这是我的测试代码(每个案例只有main.cpp 不同):
worker.h:
#include <QObject>
#include <QDebug>
#include <QThread>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0) { this->isRunning_ = false;}
bool isRunning() const { return isRunning_; }
signals:
void processingFinished();
void inProgress();
public slots:
void process()
{
this->isRunning_ = true;
qDebug() << this << "processing started";
for (int i = 0; i < 5; i++)
{
QThread::usleep(1000);
emit this->inProgress();
}
qDebug() << this << "processing finished";
this->isRunning_ = false;
emit this->processingFinished();
}
private:
bool isRunning_;
};
workermanager.h:
#include "worker.h"
class WorkerManager : public QObject
{
Q_OBJECT
public:
explicit WorkerManager(QObject *parent = 0) :
QObject(parent) {}
public slots:
void process()
{
QThread *thread = new QThread();
Worker *worker = new Worker();
connect(thread,SIGNAL(started()),worker,SLOT(process()));
connect(worker,SIGNAL(processingFinished()),this,SLOT(slot1()));
connect(worker,SIGNAL(inProgress()),this,SLOT(slot2()));
worker->moveToThread(thread);
qDebug() << "starting";
thread->start();
QThread::usleep(500);
while(worker->isRunning()) { }
qDebug() << "finished";
}
void slot1() { qDebug() << "slot1"; }
void slot2() { qDebug() << "slot2"; }
};
main.cpp(案例 1 -
workerManager没有单独的线程):
#include <QCoreApplication>
#include "workermanager.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WorkerManager* workerManager = new WorkerManager;
workerManager->process();
qDebug() << "end";
return a.exec();
}
输出 -
slot1和slot2都在a.exec()调用(??? - 使用主事件循环?):
starting
Worker(0x112db20) processing started
Worker(0x112db20) processing finished
finished
end
slot2
slot2
slot2
slot2
slot2
slot1
main.cpp(案例 2 -
workerManager移动到单独的线程,但线程未启动):
#include <QCoreApplication>
#include "workermanager.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WorkerManager* workerManager = new WorkerManager;
QThread *thread = new QThread();
workerManager->moveToThread(thread);
workerManager->process();
qDebug() << "end";
return a.exec();
}
输出 - 既没有调用
slot1也没有调用slot2- (??? 与线程相关的事件循环接收信号,但由于线程没有启动,所以没有调用插槽?):
starting
Worker(0x112db20) processing started
Worker(0x112db20) processing finished
finished
end
main.cpp(案例 3 -
workerManager移动到单独的线程,线程已启动但workerManager::process()通过workerManager->process()调用):
#include <QCoreApplication>
#include "workermanager.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WorkerManager* workerManager = new WorkerManager;
QThread *thread = new QThread();
workerManager->moveToThread(thread);
thread->start();
workerManager->process();
qDebug() << "end";
return a.exec();
}
输出 -
slot2被调用,而Worker仍在执行其process()(???):
starting
Worker(0x197bb20) processing started
slot2
slot2
slot2
slot2
Worker(0x197bb20) processing finished
finished
end
slot2
slot1
main.cpp(案例 4 -
workerManager移动到单独的线程,线程已启动,但使用来自thread的started()信号调用了workerManager::process()):
#include <QCoreApplication>
#include "workermanager.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
WorkerManager* workerManager = new WorkerManager;
QThread *thread = new QThread();
workerManager->moveToThread(thread);
QObject::connect(thread,SIGNAL(started()),workerManager,SLOT(process()));
thread->start();
qDebug() << "end";
return a.exec();
}
OUTPUT - 到达
a.exec()(???) 后处理的所有事件:
end
starting
Worker(0x7f1d700013d0) processing started
Worker(0x7f1d700013d0) processing finished
finished
slot2
slot2
slot2
slot2
slot2
slot1
感谢您的任何澄清。
【问题讨论】:
标签: c++ multithreading qt event-loop signals-slots