我看过很多关于 QThread 和在 QThreads 之间移动 QObjects 的帖子和文章,但唉,它仍然让我头疼。这是我试图采用的模式:
#include "connectionthread.h"
#include <cassert>
ConnectionThread::ConnectionThread(ConnectionPtr const &connectionPtr) :
worker(NULL),
m_connectionPtr(connectionPtr)
{
connect(this, SIGNAL(executeSignal()), this, SLOT(loginProcess()));
}
void
ConnectionThread::start()
{
if(worker) {
if(worker->isRunning()) {
worker->quit();
}
delete worker;
}
worker = new QThread;
connect(worker, SIGNAL(started()), this, SLOT(run()));
worker->start();
}
void
ConnectionThread::run()
{
emit executeSignal();
}
void
ConnectionThread::loginProcess()
{
m_connectionPtr->Connect();
}
现在在主 GUI 线程中创建了一个实例,但是当最终调用 loginProcess 时,它会阻塞直到完成,这会导致我的应用程序的 GUI 挂起。请注意,如果我将逻辑代码直接放入 run 函数并省略如下信号,则不会观察到差异:-
void
ConnectionThread::run()
{
m_connectionPtr->Connect();
}
所以我假设我需要将“this”移动到名为 worker 的线程中,例如:
void
ConnectionThread::start()
{
if(worker) {
if(worker->isRunning()) {
worker->quit();
}
delete worker;
}
worker = new QThread;
this->moveToThread(worker);
connect(worker, SIGNAL(started()), this, SLOT(run()));
worker->start();
}
但这给了我
QObject: Cannot create children for a parent that is in a different thread.
我不确定为什么会这样,但是因为创建了 ConnectionThread 的一个实例并且它的 start 函数是从另一个线程调用的。让我们称这个其他线程为 GuiThread。这意味着 GuiThread 具有控制权,因此应该能够将 ConnectionThread 实例的所有权转移给工作线程。
我尚未完全探索的最后一种可能性是将 m_connectionPtr 移动到工作线程的可能性。
关于上述模式的任何想法,我如何改进它,以及一般我如何防止它阻塞?