TSG*_*TSG 1 c++ qt multithreading move qobject
为了简化我的清理工作,我想将我的worker对象的父对象设置为它所移动的Qthread.(见下文).
void TelnetServer::incomingConnection(qintptr socketDescriptor)
{
QThread * TelnetConnectionThread = new QThread(this);
TelnetConnection *worker = new TelnetConnection(socketDescriptor,TelnetConnectionThread);
connect(TelnetConnectionThread, SIGNAL(started()), worker, SLOT(start()));
connect(TelnetConnectionThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
worker->moveToThread(TelnetConnectionThread); // Move worker into QThread
TelnetConnectionThread->start();
}
Run Code Online (Sandbox Code Playgroud)
在start()行之前,我添加了:
worker->setParent(TelnetConnectionThread);
Run Code Online (Sandbox Code Playgroud)
但在运行时我看到一个错误,我无法做到这一点,因为新的父级在不同的线程.怎么可能?在上面的行中,我将worker移动到新线程...因此worker应该与TelnetConnectionThread位于同一个线程中.救命?
我确认了一些qDebug和thread()工作者实际上已经转移到了新的线程!
我觉得你对QThread有点困惑.第一个问题是它的名称相当误导,因为它实际上不是一个线程,而是一个线程控制器.接下来是线程关联性问题(对象实际运行的线程).
如果我们从主线程开始并创建一个新的QThread,则在主线程中实例化线程控制器: -
QThread* pThread = new QThread;
Run Code Online (Sandbox Code Playgroud)
接下来线程启动: -
pThread->start();
Run Code Online (Sandbox Code Playgroud)
即使pThread被认为是在不同的线程中运行,它的线程亲和性仍然是主线程,但任何移动到pThread的基于QObject的类实例都将具有新线程的线程亲和性: -
QObject* pObject = new QObject;
pObject->moveToThread(pThread);
Run Code Online (Sandbox Code Playgroud)
仍然,pThread的线程亲和力是主线程,而pObject的线程亲和力是新线程; 记住,pThread实际上是一个线程控制器!
将pObject的父节点设置为pThread是错误的,因为它们具有不同的线程亲和性.这是许多人在尝试从QThread继承时遇到的问题,而不是将其用作单独的实体并将QObject移动到它.通常会发生的事情是,对象有时是在其继承的QThread类的构造函数中创建的,没有对它们进行父化,也没有意识到这些对象将具有主线程的线程亲和性,而不是他们期望的新线程.
将QObject移动到另一个线程也会移动它的子节点,因此尝试将父节点设置为线程(线程控制器!)没有意义.
总而言之,您不能将工作对象的父级设置为TelnetConnectionThread,因为它们在不同的线程上运行.
但是,如果您在完成后尝试自行清理线程,则可以执行以下操作: -
connect(TelnetConnectionThread, SIGNAL(finished()), TelnetConnectionThread, SLOT(deleteLater()));
Run Code Online (Sandbox Code Playgroud)