2016-01-02 62 views
0

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

的问题是,我想在一个QAbstractTableModel使用这些数据,我可以简单地从我重写data()columnCount()rowCount()使用存取功能,我实现并获得一个项目在一个时间。但我认为这是不够的,因为在后续的两个调用data()之间,另一个线程可能会跳入并更改项目数(例如rowCount()),并且模型的线程可能最终访问超出界限的数据。

我想我需要的columnCount()和模型复位rowCount()最先调用之前锁定的互斥体,和解锁,只有当所有的数据读入模型(以data()最后一次通话后),有没有这样做的方式?还是我在想错误的方式?

我想拷贝共享数据结构到模型重置的本地一个(并且只有在复制操作时才锁定互斥锁),并且在那之后安全地访问复制的数据,但这不是过度杀伤?没有更有效的解决方案吗?

回答

1

在Qt的Model-View框架中,QAbstractItemModel和QAbstractItemView之间的接口根本不是线程安全的,它被设计为只与一个线程一起使用,它必须是GUI线程,也就是说, GUI不能在主(GUI)线程以外的其他线程中安全地完成。

因此,模型必须保存自己的数据并将其与实际数据同步。如果数据集很大,则可以依靠fetchMore()来避免复制每个模型实例中的全部数据。看看在QtSql's sql models code中做了什么。然后,您提出的锁定电话问题更容易解决。

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

+0

PS:您仍然可以在几个模型实例之间共享数据,因为所有视图都由主(GUI)线程执行,并且不会同时调用两个模型。 – Jim

+0

感谢您的回答,我想我将不得不切换到单线程设计,以避免这样的问题 – Mike