gpt4 book ai didi

c++ - 从另一个(非 qt)线程调用 QObject 方法的线程安全性?

转载 作者:太空宇宙 更新时间:2023-11-04 13:08:46 24 4
gpt4 key购买 nike

我有两个对象,它们位于不同的线程中,我试图确定所使用的模式是否是线程安全的。

第一个对象是 QObject 派生的,存在于(创建于)主 Qt 线程中。该类包含一些应从 QML 调用的 Q_INVOKABLE 方法、一些定义为 signals:signal*() 方法和一些 Emit *() (普通)方法,我用作包装器来发出信号。例如:

void MyQObjectClass::EmitStatus(void) {
emit signalStatusChange(_status);
}

我通常在 QML 中监听这些信号。

第二个对象不是 QObject 派生的,存在于第二个线程 (pthread) 中。该线程运行自己的事件循环 (libev) 并分派(dispatch)事件。我不能在此线程中使用与 Qt 相关的任何内容,因为我需要自定义 libev 事件循环。在这个对象上,我定义了一些 Notify*() 方法,这些方法将通过 libev 发送异步事件以供回调接收。

我需要能够在两个对象/线程之间进行通信,但我不确定如何安全地进行通信。

实际的设计是让pthread线程对象直接调用不同的Emit*()方法,这样QObject就可以正确的将信息传递给Qt/QML。如果我需要将信息从 Qt/QML 发送到 pthread/libev 对象,我将调用(从 Qt 线程)Notify*()方法。

阅读时Accessing QObject Subclasses from Other Threads ,它说:

QObject and all of its subclasses are not thread-safe. This includes the entire event delivery system.

但进一步指出:

On the other hand, you can safely emit signals from your QThread::run() implementation, because signal emission is thread-safe.

所以我的问题是,上面描述的设计是线程安全的吗?我能否安全地调用 myQObject->EmitMySignal(),而后者又会调用 emit signalMySignal(),所有这些都来自 pthread 对象?

最佳答案

我将演示如何使用事件而不是您不能使用的信号和插槽来实现您想要的(因为一侧不是 QObject 派生的)

class MyObjectClass : public QObject
{
Q_OBJECT
public:
virtual bool event(QEvent *event) override
{
bool result = true;

if(event->type() == QEvent::User+1)
emit signalStatusChange(_status);
else
result = QObject::event(event); //call direct parent's event here!

return result;
}
};

在您的另一个线程中,您将执行此操作:

MyObjectClass *p; //holds pointer to the instance in main thread
qApp->postEvent(p, new QEvent(QEvent::User+1));

这将检索指向位于主线程中的应用程序的指针,并将事件发布到其事件循环中。然而,事件将从调用中异步处理,因此行为将与您现在所做的不同。但它会更安全,恕我直言,更优雅。您可以根据需要添加任意数量的类型。如果您还没有处理事件,请不要忘记将事件传播给父级!

关于c++ - 从另一个(非 qt)线程调用 QObject 方法的线程安全性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40916479/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com