1

为了减轻我的清理工作,我想将我的工作对象的父对象设置为它移动到的 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();  
}

在 start() 行之前,我添加了:

worker->setParent(TelnetConnectionThread);

但在运行时我看到一个错误,我不能这样做,因为新的父级在不同的线程中。这个怎么可能?在上面的行中,我将工作线程移到了新线程……所以工作线程应该与 TelnetConnectionThread 在同一个线程中。帮助?


我用一些 qDebug's 和 thread() 确认了 worker 实际上确实被转移到了新线程!

4

1 回答 1

5

我认为您对 QThread 有点困惑。第一个问题是它的名字相当具有误导性,因为它实际上不是一个线程,而是一个线程控制器。接下来是线程亲和性问题(对象实际运行的线程)。

如果我们在主线程中启动并创建一个新的 QThread,线程控制器在线程中被实例化:-

QThread* pThread = new QThread;

接下来启动线程: -

pThread->start();

即使 pThread 被认为在不同的线程中运行,它的线程亲和性仍然是线程,但是任何移动到 pThread 的基于 QObject 的类实例都将具有新线程的线程亲和性:-

QObject* pObject = new QObject;
pObject->moveToThread(pThread);

尽管如此,pThread 的线程亲和性是线程,而 pObject 的线程亲和性是新线程;请记住,pThread 实际上是一个线程控制器!

将 pObject 的父级设置为 pThread 是错误的,因为它们具有不同的线程亲和性。这是很多人在尝试从 QThread 继承时遇到的问题,而不是将其用作单独的实体并将 QObjects 移至其中。通常发生的情况是,对象有时是在其继承的 QThread 类的构造函数中创建的,而不是父级,也没有意识到这些对象将具有主线程的线程亲和性,而不是他们期望的新线程。

将 QObject 移动到另一个线程也会移动其子级,因此尝试将父级设置为线程(线程控制器!)没有意义。

总而言之,您不能将工作对象的父对象设置为 TelnetConnectionThread,因为它们在不同的线程上运行。

但是,如果您尝试在完成后自行清理线程,您可以这样做:-

connect(TelnetConnectionThread, SIGNAL(finished()), TelnetConnectionThread, SLOT(deleteLater()));
于 2013-10-10T15:51:45.760 回答