繁体   English   中英

使用QAbstractTableModel中多个线程之间共享的数据

[英]using data shared between multiple threads in a QAbstractTableModel

我有一个使用Q_GLOBAL_STATIC实现的单例类,该类包含必须从多个线程访问的数据结构,我在该类中实现了访问器函数,该函数将在访问数据之前锁定互斥体,以便对共享数据的所有访问都被序列化。

问题是我想在QAbstractTableModel使用此数据,我可以简单地使用实现的访问器函数,并一次从覆盖的data()columnCount()rowCount()访问一项。 但是我认为这是不够的,因为在两次随后的对data()调用之间,另一个线程可能会跳入并更改项数(例如rowCount() ),并且该模型的线程可能最终会访问超出范围的数据。

我认为我需要在首次重置模型的columnCount()rowCount()之前锁定互斥锁,并且仅在将所有数据读入模型(最后一次调用data() )时才将其解锁有办法吗? 还是我想错了方向?

我想到了在模型重置时将共享数据结构复制到本地结构(并且仅在复制操作上锁定了互斥锁),然后安全地访问复制的数据,但这不是一个过大的功能吗? 没有更有效的解决方案吗?

在Qt的Model-View框架中,QAbstractItemModel和QAbstractItemView之间的接口根本不是线程安全的,它被设计为仅与一个线程一起使用,该线程必须是GUI线程,即主线程,因为视图确实是在GUI上绘制的,因此无法在除主(GUI)线程之外的其他线程中安全地完成操作。

因此,模型必须拥有自己的数据,并将其与真实数据同步。 如果数据集很大,则可以依靠fetchMore()避免在每个模型实例中复制整个数据。 查看QtSql的sql模型代码中完成的操作 这样一来,您提出的通话间锁定问题就更容易解决。

如果实际数据持有者对象能够发出连接到模型实例的信号,您甚至可以事件驱动的方式更新模型。 由于自动/排队信号连接,模型插槽将在主(GUI)线程中执行,因此不需要使用QAbstractItemModel-QAbstractItemView接口实现线程安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM