【问题标题】:Writing to a SQLite database from multiple threads [duplicate]从多个线程写入 SQLite 数据库 [重复]
【发布时间】:2015-10-26 11:58:33
【问题描述】:

我正在编写一个 QT 应用程序来监控一些统计数据。在主窗口中,您选择多个(或仅一个)项目并为它们打开一个图形窗口。每个项目都是从不同的线程轮询的。

每次获取数据都是写在SQLite数据库中,但是遇到了一个问题:

我正在使用 SSD 驱动器的计算机上创建此应用程序,它运行正常,但是当我在具有 HDD 的计算机上运行它时,应用程序崩溃(崩溃发生在 QT sqlite dll 文件 - qsqlite.dll 中)。我用谷歌搜索了这个问题,发现很多人说不建议将 sqlite 用于此类用途。当我写入数据库时​​,我还使用 QMutex 来锁定/解锁这些部分,但不幸的是它不能解决问题。

有没有办法可以为此使用 sqlite 或者我必须寻找不同的数据库,例如 postgres ?

感谢您的宝贵时间!

【问题讨论】:

  • 你在使用 sqlite 的锁定和/或事务吗?
  • 从每个线程打开一个单独的数据库连接。不要在线程之间共享相同的数据库连接。

标签: c++ multithreading qt sqlite


【解决方案1】:

我从不喜欢一个应用程序中的多个数据库连接。

在您的情况下,我希望为所有 write-SQL 语句实现一个队列 (FIFO),并仅通过一个连接将它们发送到数据库。由于您将从多个线程写入队列,因此您必须使用互斥锁等来保护对队列的写入。

这样,唯一的线程争用是在您的代码中,SQLite 驱动程序不必太辛苦。

我还会考虑缓存读取查询中的数据,这样您只请求您还没有的数据。也就是说,请求最近的 100 个值并将它们保存在一个数组或列表中,然后当您下次请求值时,只请求数组中最后一个值的值。

【讨论】:

  • 谢谢你的想法。它似乎在我的情况下完美运行(需要更多测试)。我是这样设计的:我每 10 秒检查一次队列中是否有项目(QString 向量)。如果是,我将每个项目放在 QSQLQuery 中并执行它们(FIFO)。要将项目添加到队列中,我使用信号/插槽。我在添加到队列和检查队列时使用互斥锁。
  • @user2195430 感谢您的更新 - 我很高兴它为您解决了问题。
  • 也实现了这个方法。最有意义、变化很小、安全且效果很好。
猜你喜欢
  • 2013-12-24
  • 1970-01-01
  • 2017-02-08
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多