[英]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.