【问题标题】:Concurrent updates of relational application data关系应用程序数据的并发更新
【发布时间】:2015-04-13 10:24:13
【问题描述】:

我们有一个 Qt C++ Gui 应用程序,它基本上是服务器 (TCP) 软件控制它并显示其数据的终端。

问题是来自服务器的数据是高度相关的数据。 在 SQL 术语中,大约有 10-15 个表都通过一些外键相互连接

此数据由服务器更新,并且必须(同时)由 GUI 显示。

目前的解决方案是我们将所有数据(基本上)存储在具有适当锁定(读/写)的映射和结构中,以避免并发访问问题。

我们现在面临的问题是这个解决方案不能很好地扩展。应用程序的性能(点击屏幕延迟发生的事情)变得更糟。

使用应用程序中的关系数据库系统(例如带有内存数据库的 sqlite)会有帮助吗? 使用数据库(在查询时解决关系依赖关系)是否比使用结构映射(在插入期间解决关系依赖关系)更好的扩展?

我希望我尽可能清楚地说明我的问题。

问候, 安德烈


为了更清楚:这是关于 GUI 不再响应,因为来自服务器的许多更新锁定了数据结构。

【问题讨论】:

  • 问题:用户在 GUI 中输入命令,然后发送到服务器,服务器响应更多数据(基于查询)?
  • 我担心“锁定”是指从客户端向服务器发送锁定请求,以锁定成功/失败响应,成功后继续更新?因为这解释了缓慢。
  • 啊,好吧,还不清楚...忽略客户端对服务器所做的事情。这都是关于来自服务器的数据。处理数据(将其放入正确的地图中)实质上会阻止 GUI 线程进行绘制。一个因此的问题:在这种情况下,RDB 会有所帮助吗
  • 不,不会。数据以“原始”形式出现:您将转换为 SQL + INSERT + SELECT + GUI 适应开销,只是为了显示一些东西。使用线程收集数据,然后提醒 GUI。
  • 我们目前正在使用多个线程(1 个用于 GUI 绘图)和一个事件线程来处理传入事件。但是数据结构的锁定正在扼杀我们的性能。

标签: c++ qt data-structures concurrency relational-database


【解决方案1】:

(根据说明实际问题的更新评论,UI线程阻塞)

这里有两个简单的修复方法可以提供帮助。第一个问题是在锁定共享数据结构之前预处理所有传入的数据。例如,如果您在地图中有std::string,请不要在地图上锁定时将const char* 转换为std::string。这将在保持 UI 线程时调用strlen。相反,先转换然后锁定地图。

第二个改进是锁定 GUI 的时间更短。如果更新可以划分为多个较小的部分,请反复获取和释放锁。这意味着实际更新速度较慢,但​​ UI 响应速度更快。

一个更复杂的策略(如果分区是不可能的)是暂存。在新地图中创建所有新条目,然后合并两个地图。这基本上是对类固醇的预处理,因为您现在还对新条目进行了排序。 (我希望你与服务器交换差异,而不是每次都完全刷新数据!)

【讨论】:

  • 好主意。我们正在进行增量更新,但有大量(我们称之为)初始更新......到目前为止,所有增量更新。这发生在中午重新连接期间。
  • 在添加到容器之前准备更新是我们已经在做的事情(以共享指针的形式)。但是为了确保关系约束成立,我们仍然必须锁定多个容器。 (这样读者就不会看到损坏的状态)
  • @Bigbohne:保证引用完整性是数据库的责任,而不是 UI 的责任。我希望您不要花时间阻塞 UI 线程来保证这种完整性?甚至可能值得拥有两份数据副本,一份用于 UI,一份用于增量更新。每次更新后,制作新数据的副本(当时是第三个副本),锁定,将副本与 UI 的副本交换(这是即时 - 根节点指针交换),解锁并丢弃旧的 UI 数据。
猜你喜欢
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 2013-12-17
  • 2017-10-14
  • 1970-01-01
相关资源
最近更新 更多