小巧、快速、可靠。
三者选其二。
在多线程应用程序中使用 SQLite

1. 概述

SQLite 支持三种不同的线程模式

  1. 单线程。在此模式下,所有互斥锁都已禁用,并且 SQLite 在一次仅使用一个线程的情况下是不安全的。

  2. 多线程。在此模式下,SQLite 可由多个线程安全使用,前提是单个 数据库连接 或任何从数据库连接派生的对象(例如 预备语句)不会同时在两个或多个线程中使用。

  3. 序列化。在序列化模式下,影响或使用任何 SQLite 数据库连接 或任何从这种数据库连接派生的对象的 API 调用可以从多个线程安全地执行。对单个对象的影响与从单个线程按相同顺序执行所有 API 调用的效果相同。名称“序列化”源于 SQLite 使用互斥锁来序列化对每个对象的访问。

线程模式可以在编译时(编译 SQLite 库的源代码时)或启动时(启动打算使用 SQLite 的应用程序时)或运行时(创建新的 SQLite 数据库连接时)选择。一般来说,运行时会覆盖启动时,启动时会覆盖编译时。但是,单线程模式一旦选中就不能覆盖。

默认模式为序列化。

2. 编译时选择线程模式

使用 SQLITE_THREADSAFE 编译时参数选择线程模式。如果不存在 SQLITE_THREADSAFE 编译时参数,则使用序列化模式。这可以通过 -DSQLITE_THREADSAFE=1 显式设置。使用 -DSQLITE_THREADSAFE=0,线程模式为单线程。使用 -DSQLITE_THREADSAFE=2,线程模式为多线程。

sqlite3_threadsafe() 接口的返回值是编译时设置的 SQLITE_THREADSAFE 的值。它不反映通过 sqlite3_config() 接口或作为 sqlite3_open_v2() 的第三个参数给出的标志在运行时对线程模式所做的更改。

如果在编译时选择了单线程模式,则关键互斥锁逻辑将从构建中省略,并且无法在启动时或运行时启用多线程模式或序列化模式。

3. 启动时选择线程模式

假设编译时线程模式不是单线程,则可以使用 sqlite3_config() 接口在初始化期间更改线程模式。SQLITE_CONFIG_SINGLETHREAD 动词将 SQLite 置于单线程模式,SQLITE_CONFIG_MULTITHREAD 动词设置多线程模式,SQLITE_CONFIG_SERIALIZED 动词设置序列化模式。

4. 运行时选择线程模式

如果在编译时或启动时未选择单线程模式,则可以创建单个数据库连接为多线程或序列化。无法将单个数据库连接降级为单线程模式。如果编译时或启动时模式为单线程,则无法升级单个数据库连接。

单个数据库连接的线程模式由作为 sqlite3_open_v2() 的第三个参数给出的标志确定。SQLITE_OPEN_NOMUTEX 标志导致数据库连接处于多线程模式,而 SQLITE_OPEN_FULLMUTEX 标志导致连接处于序列化模式。如果未指定任何标志,或者使用 sqlite3_open()sqlite3_open16() 而不是 sqlite3_open_v2(),则使用由编译时和启动时设置确定的默认模式。

本页最后修改于 2023-12-05 14:43:20 UTC