【问题标题】:sqlite ios thread accesssqlite ios线程访问
【发布时间】:2012-07-03 11:50:10
【问题描述】:

我正在尝试编写一个多线程(使用 NSOperationQueues 进行写入并在主线程上执行读取)应用程序来访问 sqlite 数据库数据。我知道 sqlite 默认不是线程安全的,但我们添加了多线程预处理器宏并将我们的日志模式设置为 wal。

根据这个 sqlite 文档:http://www.sqlite.org/faq.html#q6 看来我们需要在编写任何内容之前完成所有准备好的语句。这是真的?有没有办法避免这种情况?如果我们对同一个数据库有两个句柄怎么办?

基本上,我们希望一次进行多次读取和一次写入,但正在尝试找出最佳方法。

提前致谢。

【问题讨论】:

  • 所以要么完成这件事并进行马马虎虎的线程化,要么不完成并冒着双重或更多线程访问资源的风险(一个巨大的禁忌)?
  • 我们的第二个线程(使用 nsoperationqueue)只会访问写入...所有读取都在主线程上,因此它们不会共享资源
  • 好吧,我想解决这个问题的唯一方法就是自己尝试一下。 iOS 类似于 UNIX,所以我想知道他们的建议到底能走多远……+1
  • 它可能一开始可以工作,但不幸的是很难测试多线程来重现任何错误 =(

标签: objective-c ios sqlite


【解决方案1】:

线程模式由编译时间、启动或运行时选项决定。更多细节在这里:

http://www.sqlite.org/threadsafe.html

文档说序列化是默认设置,这意味着您可以从多个线程中使用 - 它会在所有访问被序列化的情况下保护您。如果你想要更多的并行性,你可以使用多线程模式和多个连接对象。

如果您使用多线程,请确保同一数据库连接对象在任何一个时间点不被多个线程使用:

多线程。在这种模式下,SQLite 可以被多人安全使用 线程,前提是不使用单个数据库连接 同时在两个或多个线程中。

但是,请确保复杂性是合理的。与所有性能问题一样,在之前和之后进行测量。

编辑:确保这一点的一种方法是创建自己的池机制。创建一个包含 n 个连接句柄的池,每个并行任务获取并释放到池中。文档说多线程模式在连接之间是完全安全的。这样,您就不必担心所有其他交易或报表都已完成。单独的读取线程/连接和写入线程/连接实际上是一个非常简单的硬编码池。

【讨论】:

  • 所以基本上有两个句柄...一个用于在主线程上读取,一个用于在后台线程上写入?
  • 而不是依赖于没有交易和所有要最终确定的语句,另一种方法是池化方法。由于已知多线程模式使用不同的连接句柄是安全的,因此请创建一个包含 n 个连接句柄的池,供并行任务使用。
  • 所以你是说两个手柄可以解决我的问题?一读一写?
  • 我建议您在一个池中有一个包含 n 个连接的池。并行任务可以从池中获取/租用连接,使用它,将其返回到池中。这样,一个连接就保证一次只能被一个线程使用,你可以通过池和共享来保持低连接,并且你是安全的。但是...
  • 但是……确保你需要那种复杂性。确保你测量。你的应用程序是如何工作的?是否有一个带有后台写入的主应用程序线程读取?如果是这样,那么最简单的池是单个读者和作者,您将获得最大的收益。你的交易时间短吗?然后,可能是多线程,所有这些都是多余的,序列化的默认值就足够了......如果不了解数据访问模式和测量,很难说。越简单越好...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-27
相关资源
最近更新 更多