答案:SQLite 是线程安全的。由于很多用户会忽略我们在上一段中给出的建议, 我们做出了这种让步。但是,为了达到线程安全,SQLite在编译时必须将 SQLITE_THREADSAFE 预处理宏置为1。在Windows和Linux上, 已编译的好的二进制发行版中都是这样设置的。 如果不确定你所使用的库是否是线程安全的,可以调用 sqlite3_threadsafe() 接口找出。 在 3.3.1 版本之前,一个 sqlite3 结构只能被用于调用 sqlite3_open 创建的同一线程。你不能在一个线程中打开数据库, 然后将数据库句柄传递给另外一个进程使用。 这主要是由于在好多通用的线程实现(如RedHat9)中的限制引起的(是Bug吗?)。 特别的,在有问题的系统上,一个进程创建的 fcntl() 锁无法被其它线程清除或修改。 所以,由于 SQLite 大量使用 fcntl() 锁做并发控制, 如果你在不同的线程间移动数据库连接,就可能会出现严重的问题。
在3.3.1版本上,关于在线程间移动数据库连接的限制变得宽松了。 在它及以后的版本中,只要连接没有持有 fcntl() 锁,在线程间移动句柄是安全的。 如果没有未决的事务,并且所有的语句都已执行完毕, 你就可以安全的假定不再持有任何锁。
在UNIX中,在执行 fork() 系统调用时不应携带已打开的数据库进入子进程。 那样做将会有问题。 |