moveToThread(nullptr)`是从其源线程中提取目标线程内QObject的有效方法吗?

问题描述 投票:4回答:1

假设对象obj是否属于QThread T1。理想情况下,具有Qhread T2功能的obj不能从T1“拉”到T2moveToThread()文档中提到了这一点:

警告:此函数不是线程安全的;当前线程必须与当前线程亲和力相同。换句话说,此函数只能将对象从当前线程“推”到另一个线程,而不能将对象从任意线程“推”到当前线程。 但是,此规则有一个例外:没有线程亲缘关系的对象可以“拉”到当前线程。

moveToThread()的观点3暗示实际上是“撒谎的孩子”。因为answer将使对象可从其他线程移动。这是没有副作用的惯用方法吗?

moveToThread(nullptr)

附加问题:如果在第1行和第2行之间的void FunctionRunningInT2 (QObject& obj) // `obj` belongs to thread `T1` { obj.moveToThread(nullptr); // line-1 no event processing for obj!? obj.moveToThread(T2); // line-2 is it OK ??? } 上发出了任何signal,会发生什么?Rephrased:在obj的情况下,以后不接收任何信号。但是,仍处理obj.disconnect()之前的未决信号。 disconnect()是否也正确?还是也会丢弃未决信号?

c++ multithreading qt idioms qobject
1个回答
2
投票

据我了解,一个人不能在另一个线程中的对象上调用moveToThread(nullptr)。即使参数为moveToThread,您也将收到来自Qt的以下消息:

nullptr

并且该对象不会从其线程中移动。

将对象到另一线程的安全方法是使用排队连接,即为可移动对象提供一个类似的插槽

QObject::moveToThread: Current thread ( ... ) is not the object's thread ( ... )
Cannot move to target thread (0x0)

这样,可以在mover对象中使用信号,例如

class Moveable : public QObject
{
    Q_OBJECT
public:
    Moveable() : QObject(nullptr) {}

public slots:
    void moveMe(QThread * destination) { moveToThread(destination); }

连接他们

class Mover : public QObject
{
    Q_OBJECT
signals:
    void moveIt(QThread *);

以及任何需要的地方

connect(&mover, &Mover::moveIt, &moveable, &Moveable::moveMe, Qt::QueuedConnection);

mover.moveIt(QThread::currentThread());

[如果只是不想处理实现信号并连接它们,则可以安全地使用诸如:

mover.moveIt(to_whatever_thread);

再次利用排队的连接,但直接调用插槽。

关于附加问题。一旦将对象移动到线程QMetaObject::invokeMethod(&moveable, "moveMe", Qt::QueuedConnection, Q_ARG(QThread*, destination_thread)); ,请按0x0进行操作:

无法对该对象或其子对象进行任何事件处理,因为它们不再与任何线程关联。

因此,对象也将停止接收信号,甚至不会从也已移至here的另一个对象接收信号。

© www.soinside.com 2019 - 2024. All rights reserved.