我有3个对象(继承自QObject
)每个都包含一个单独的std::list
。每个对象都是在主 gui 线程(没有父线程)中创建的,然后被推送到它自己的线程(使用 Qt 的QObject::moveToThread()
).
每个线程都连接到一个 GUI,并在不同线程之间发送带有数据的消息。每个线程本质上都是处理它自己的列表。例如:
对象 1:数据消费者。它会弹出列表的前面(如果存在数据)以供使用。它还有一个可用的 SLOT,以便其他线程可以将数据推送到它。没有其他对象可以直接访问该列表,只有原始的 QObject 类。
目标 2:数据的生产者。它将数据推送到其列表。它有可供其他人“ping”它以获取数据的插槽,而这些数据又会发出从其列表中弹出数据的信号。没有其他对象可以直接访问该列表。
Obj 3:为 obj 1 生成数据并使用来自 obj 2 的数据。它有自己的内部数据结构,用于跟踪发送到 obj 1 的数据和来自 obj 2 的数据。它最终会将两个数据集推送到某个对象QwtPlots
在进行一些分析之后。
Obj 的 1 和 2 是实时关键的,并使用 QueryPerformanceCounter 风格的“计时”,这实际上会在它们运行时消耗 CPU。他们跑QCoreApplication::processEvents()
每个循环都处理发生的事件。
这是处理跨线程数据共享的好方法吗?如果不是,漏洞在哪里?您将如何纠正它们?我知道这会创建大量的数据“副本”,但此时内存膨胀并不是问题。
提前致谢 :)
如果没有所有实现细节,很难确切地说它是否是线程安全的,因为使用线程时有很多事情可能会出错。
对象 1:数据消费者。它会弹出列表的前面(如果存在数据)以供使用。它还有一个可用的 SLOT,以便其他线程可以将数据推送到它。没有其他对象可以直接访问该列表,只有原始的 QObject 类。
如果此槽使用排队或自动连接类型连接到其他线程(例如 Obj 3)中的信号,则 Obj 1 可能是安全的。如果直接从其他线程调用该插槽,那么它显然不是线程安全的,除非您显式同步所有内容。
目标 2:数据的生产者。它将数据推送到其列表。它有可供其他人“ping”它以获取数据的插槽,而这些数据又会发出从其列表中弹出数据的信号。没有其他对象可以直接访问该列表。
您没有提到“ping”是如何实现的或者哪些线程调用这些插槽。如果其他线程直接调用它们,并且 ping 涉及访问内部 std::list,那么您就有麻烦了。如果这些槽仅通过排队或自动连接(例如 Obj 3 中的某些信号)调用,那么就可以了。如果这些槽是线程安全的(例如,它们只将“ping”消息放入某种内部同步消息队列中),那么也没关系。不过,后一种方式看起来像是排队连接机制的自定义重新实现。
总的来说,这整件事对我来说看起来太危险了,因为可以从任何地方错误地调用插槽。我会尝试通过在那里进行一些安全检查来避免这种事情,如下所示:
void Obj2::ping() {
if (QThread::currentThread() != this->thread()) {
// not sure how efficient it is
QMetaObject::invoke(this, "ping", Qt::QueuedConnection);
return;
}
// thread unsafe code goes here
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)