1

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

问题是我想QAbstractTableModeldata(). 但我认为这还不够,因为在对另一个线程的两个后续调用之间可能会跳入并更改项目的数量,例如 ( ),并且模型的线程最终可能会访问越界数据。columnCount()rowCount()data()rowCount()

columnCount()我想我需要在模型重置的第一次调用和模型重置之前锁定互斥锁rowCount(),并且只有在将所有数据读入模型时(在最后一次调用之后data())才解锁它,有没有办法这样做?还是我想错了?

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

4

1 回答 1

2

在Qt的Model-View框架中,QAbstractItemModel和QAbstractItemView之间的接口根本不是线程安全的,它被设计成只有一个线程使用,必须是GUI线程,即主线程,因为视图是在GUI上绘制的,不能在主(GUI)线程之外的另一个线程中安全地完成。

因此,模型必须保存自己的数据并将其与真实数据同步。如果您的数据集很大,您可以依靠 fetchMore() 来避免在每个模型实例中复制整个数据。查看QtSql 的 sql 模型代码中做了什么。然后,您提出的调用间锁定问题更容易解决。

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

于 2016-01-02T18:36:52.647 回答