c++ - `moveToThread(nullptr)` 是从源线程拉出目标线程内的 QObject 的有效方法吗?

标签 c++ multithreading qt idioms qobject

假设一个对象 obj属于QThread T1 .最好在 Qhread T2的函数,obj无法从 T1 中“拉出”至 T2 .这是在 moveToThread() 中提到的文档:

Warning: This function is not thread-safe; the current thread must be same as the current thread affinity. In other words, this function can only "push" an object from the current thread to another thread, it cannot "pull" an object from any arbitrary thread to the current thread. There is one exception to this rule however: objects with no thread affinity can be "pulled" to the current thread.



answer第 3 点表明它实际上是“对 child 的谎言”。因为 moveToThread(nullptr)将使一个对象可以从其他线程移动。
这是一种没有副作用的惯用方法吗?
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 ???
}

附加问题 : 如果有的话会怎样signalobj 上发出第 1 行和第 2 行之间?
改写 : 如果是 obj.disconnect() ,之后它不接受任何信号。然而,在 disconnect() 之前未决的信号还在处理中。 moveToThread(nullptr)是真的吗?还有?或者它也会丢弃待处理的信号?

最佳答案

据我了解,就是不能打电话moveToThread在不同线程中的对象上。即使参数是 nullptr ,您最终会收到来自 Qt 的以下消息:

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


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

将对象拉到不同线程的一种安全方法是使用排队连接,即为可移动对象提供一个插槽,例如
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 :

no event processing for this object or its children can happen, as they are no longer associated with any thread.



因此,该对象也将停止接收信号,甚至不会从另一个已移动到 0x0 的对象接收信号。 .

关于c++ - `moveToThread(nullptr)` 是从源线程拉出目标线程内的 QObject 的有效方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59675298/

相关文章:

c# - 如何在 C# 中编码集合以传递给 native (C++) 代码

c++ - 没有 QObject 或插槽的 Qt connect()

c++ - OpenMP 是否将已完成部分的重用线程用于另一个部分?

c++ - 从 QString 到 Class 类型

python - 如何调整 QInputDialog、PyQt 的大小

c++ - 段错误仅在发布配置下发生

c++ - 告诉您 C++ 项目中需要哪些源文件的工具?

c++ - C++11中根据类型要求特化类模板成员函数

java - 如何杀死Java中的死锁线程?

multithreading - 使用ptrace在多线程应用程序中检测linux调试器