IT编程入门指导
这篇主要来讨论SQLite的多线程中的疑惑。
1. SQLite 支持三种线程模式
单线程(Single-thread)模式。
在此模式下,所有的互斥锁都将被禁用,相关代码被删除,SQLite 在多线程并发访问时将不再安全。但根据马克思辩证法,此模式下代码量最小,对数据库的增删改查的单次运行效率最高。
线序化(Serialized)模式
在此模式下,应用程序的多线程可以使用同一个 SQLite 数据库连接,然后一起操作数据库,此时 SQLite 内部将保证数据库的安全性。其本质是,SQLite 利用内部互斥锁使得同时想要操作数据库的线程“线序化”,也就是一个一个来,保证数据库数据的完整性和安全性。
多线程(Multi-thread)模式。
在此模式下,SQLite 数据库可被多线程连接多次,并支持多线程随机访问。
SQLite的线程模式可以在编译时、启动时或者运行时对以上线程模式做出修改。编译时意味着从 SQLite 的源码编译生成 SQLite 库文件的时候,启动时意味着某个即将要使用 SQLite 的程序初始化的时候,运行时意味着要创建一个新的 SQLite 数据库连接的时候。一般而言,运行时所做的修改将覆盖启动时的设置,而启动时的设置将覆盖编译时的设置。但单线程模式是例外,单线程模式一旦被设定就无法被修改了。
SQLite 默认的线程模式是线序化模式。
2. 编译时对线程模式的选择
使用 SQLITE_THREADSAFE 来选择不同的线程模式,具体如下:
-DSQLITE_THREADSAFE=0 单线程模式
-DSQLITE_THREADSAFE=1 线序化模式(默认)
-DSQLITE_THREADSAFE=2 多线程模式
函数 sqlite3_threadsafe() 可以返回编译时的线程模式,如果是单线程模式则其返回 false,否则它将返回 true。由于该函数的执行比启动时和运行时要早,因此无法对这两个时刻的线程模式的修改做出判断。
如果在编译时选择了单线程模式,那么用于保护临界资源的互斥锁及其相关代码将被移除,因此此后在启动时、运行时都将无法改为线序化或者多线程模式。
3. 启动时对线程模式的选择
使用 thesqlite3_config() 来修改线程模式。具体如下:
SQLITE_CONFIG_SINGLETHREAD 设置为单线程模式
SQLITE_CONFIG_MULTITHREAD 设置为多线程模式
SQLITE_CONFIG_SERIALIZED 设置为线序化模式
4. 运行时对线程模式的选择
只要在编译时没有选择单线程模式,每一个数据库在被连接时都可设置为多线程或线序化模式。
每一个数据库连接的线程模式都可以通过 sqlite3_open_v2() 的第三个函数来选择,具体如下:
SQLITE_OPEN_NOMUTEX 意味着多线程模式
SQLITE_OPEN_FULLMUTEX 意味着线序化模式
如果以上选项都没设置,或者应用程序使用了 sqlite3_open() 或者 sqlite3_open16() 接口来连接数据库,那么就使用编译时和启动时的线程模式。
今天先聊到这儿,后续关于SQLite的常见问题会陆续更新。欢迎小伙伴关注、转发、点赞、收藏、吐槽、扔鸡蛋……