关于女神SQLite的疑惑(3)

2019-08-08 15:22:36 浏览数 (1)

秘籍酷 · 微店

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的常见问题会陆续更新。欢迎小伙伴关注、转发、点赞、收藏、吐槽、扔鸡蛋……

0 人点赞