Qt:如何在模型/视图设置中同步对来自多个线程的数据的访问?
Posted
技术标签:
【中文标题】Qt:如何在模型/视图设置中同步对来自多个线程的数据的访问?【英文标题】:Qt: How to synchronize access to data from multiple threads in model/view setup? 【发布时间】:2011-12-20 00:41:48 【问题描述】:如何在 Qt 模型/视图设置中同步对从多个线程访问的数据的访问?
我正在使用 QTableView
和 Model
类。
Model
扩展 QAbstractTableModel
并具有自定义类 Net
的实例,该类包含要显示到 QTableView
到 data()
调用的实际数据(由 Model::data()
访问)
我的班级监听网络数据并在单独的线程上运行,从该线程更新它的数据(简单的固定大小的 10 个字符串数组)。
我的班级中的数据必须通过不断更新它的线程和 Qt GUI 通过在 Model
上调用 data()
来访问。
我假设我需要使用互斥锁来同步对我的字符串数组的访问,但QAbstractTableModel::data()
是一个const
方法,所以我无法将boost::mutex
锁定在其中。
在扩展QAbstractTableModel
并向QTableView
提供数据的类中同步访问数据的一般模式是什么?
【问题讨论】:
【参考方案1】:我认为 Qt 的项目视图类(如 QAbstractTableModel)和多个线程不能很好地结合在一起。问题是 QAbstractTableModel 类希望在每次数据更改时通知所有关联的视图类,并且视图类希望能够随时从数据模型中读取数据。如果更新和数据由不同的线程拥有,那么实现这一点将很难(无论如何是有效的)。我怀疑您提出的任何多线程解决方案都需要大量序列化,以至于两个线程中只有一个线程最终会同时运行,此时您实际上已经回到单线程程序,只需一个非常复杂的设计:)
如果可能的话,我的建议是将您的 10 字符串数据库移到主/Qt 线程中。您的网络操作也可以移到主线程中(使用 QSocketNotifier 对象并确保 I/O 都是非阻塞的,这样它就不会阻止 Qt 事件循环并损害 GUI 性能);或者您可以将网络保持在单独的网络线程中,并让网络线程向主/Qt 线程发送更新消息,告诉主/Qt 线程如何更新数据库/表模型。关键是让主/Qt线程完成对数据模型数据库的所有读取和写入。
【讨论】:
我第一次尝试使用 Qt 的模型/视图是在多线程代码库中,并想“嗯……是的,这似乎不起作用。” lists.qt.nokia.com/pipermail/qt-interest/2009-August/…Net
类包含我的业务逻辑并使用第三方库进行联网,因此我更喜欢将其与 Qt 模型分开(Qt 模型/视图设计文档建议类似的方法)。数据不属于不同的线程,而是在不同线程的回调中访问。我锁定数据只是为了读/写几个字符串值,到目前为止它似乎工作。我在 Model::data()
处理程序中将 const 与互斥锁进行类型转换,以便能够读取数据。 Qt
中似乎有很多东西可以在可爱的小例子中使用,但需要大量连接真实世界的代码。
@HostileFork 我看过你的链接讨论 - 这周我构建了简单的模型/视图 Qt 应用程序(我通常不做 gui 应用程序,我更喜欢网络,更喜欢 Cocoa /Mac 然后 Qt/Linux)显示 2 个表,每个表 3x10 的数据(格式化为字符串的双精度值)。该模型具有内部类,该类使用另一个具有自己的队列(我假设运行它自己的线程)的第 3 方网络库来从网络中获取数据。白天,我每分钟接近 4000 次全表更新 x2(来自 2 个来源的相同数据),每条消息都会更新表中的所有项目......到目前为止对我有用。以上是关于Qt:如何在模型/视图设置中同步对来自多个线程的数据的访问?的主要内容,如果未能解决你的问题,请参考以下文章