数据库多线程模型

全面的理解sqlite的多线程模型对于编写复杂数据存储场景的app很有必要,先来看些sqlite多线程相关的基础知识。

sqlite在多线程访问的场景下,通过db锁来控制并发,db锁有五种状态。

  • Unlocked:默认状态。
  • Shared:共享锁,多个读线程可以同时持有共享锁,共享锁存在时,不允许写操作发生。
  • Reserved:当某个线程尝试写操作时,先持有Reserved锁,如果有多个写操作同时发生,只有一个能获得Reserved锁,当某个写线程持有Reserved锁时,其他的读线程还是可以继续加入持有Shared锁。简单来说,Reserved锁排斥其他写操作,不排斥读操作。
  • Pending:某个获得Reserved锁的写操作会进一步变为Pending锁,此时新的读操作和写操作都是不能进入的,等待所有现有的写操作(Shared锁)释放之后,下一步变为Exclusive。
  • Exclusive:写操作从Pending变为Exclusive,此时写操作可以安全进行。

从上面的几种锁状态可以得出结论,sqlite支持多个读操作并发执行,但同时只能有一个写操作在发生。从Reserved开始一直到Exclusive,都只能有一个写操作在进行,但在Pending之前,新的读操作都是可以继续加入,这种粒度的锁对多线程读写并发场景下读操作有较好的支持,同时也通过Pending锁避免了write starvation的问题。

针对上述锁的分析,我们在建立多线程模型的时候,主要有以下几种模型:

1.读和写都在主线程。
2.读在主线程,一个子线程复杂全部的写。
3.读在主线程,多个子线程负责并发的写。

第一种是最简陋的做法,写操作会影响UI线程的性能。第二种是比较普遍的做法,写操作都放到子线程当中,当然子线程也可以产生读操作,这种做法可以做到读写并发,同时又不影响UI线程。第三种做法使用多个写线程来提高写操作的效率,但从上面锁状态可以看出,从Reserved开始就已经是写操作互斥了,我个人感觉这种做法对写操作性能的提升相当有限。一般推荐第二种做法。

转载地址:
http://mrpeak.cn/blog/ios-database/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容