@H_301_8@ 单线程:这种模式下,没有进行互斥,多线程使用不安全。禁用所有的mutex锁,并发使用时会出错。当sqlite编译时加了sqlITE_THREADSAFE=0参数,或者在初始化sqlite前调用sqlite3_config(sqlITE_CONFIG_SINGLETHREAD)时启用。
@H_301_8@ 多线程:这种模式下,只要一个数据库连接不被多个线程同时使用就是安全的。源码中是启用bCoreMutex,禁用bFullMutex。实际上就是禁用数据库连接和prepared statement(准备好的语句)上的锁,因此不能在多个线程中并发使用同一个数据库连接或prepared statement。当sqlite编译时加了sqlITE_THREADSAFE=2参数时默认启用。若sqlITE_THREADSAFE不为0,可以在初始化sqlite前,调用sqlite3_config(sqlITE_CONFIG_MULTITHREAD)启用;或者在创建数据库连接时,设置sqlITE_OPEN_NOMUTEX flag。
@H_301_8@为了达到线程安全,sqlite在编译时必须将 sqlITE_THREADSAFE 预处理宏置为1。在Windows和Linux上, 已编译的好的二进制发行版中都是这样设置的。 如果不确定你所使用的库是否是线程安全的,可以调用 sqlite3_threadsafe() 接口找出。 调用sqlite3_threadsafe()可以获得编译期的sqlITE_THREADSAFE参数。
编译时选择线程模式
@H_301_8@可以通过定义sqlITE_THREADSAFE宏来指定线程模式。如果没有指定,默认为串行模式。定义宏sqlITE_THREADSAFE=1指定使用串行模式;=0使用单线程模式;=2使用多线程模式。
@H_301_8@sqlite3_threadsafe()函数的返回值可以确定编译时指定的线程模式。如果指定了单线程模式,函数返回false。如果指定了串行或者多线程模式,函数返回true。由于sqlite3_threadsafe()函数要早于多线程模式以及启动时和运行时的模式选择,所以它既不能区别多线程模式和串行模式也不能区别启动时和运行时的模式。
@H_301_8@最后一句可通过sqlite3_threadsafe函数的实现来理解sqlITE_API int sqlite3_threadsafe(void){ return sqlITE_THREADSAFE; }如果编译时指定了单线程模式,那么临界互斥逻辑在构造时就被省略,因此也就无法在启动时或运行时指定串行模式或多线程模式。
启动时选择线程模式
@H_301_8@运行时选择线程模式