多线程SQLite崩溃

时间:2012-01-20 22:03:27

标签: c++ multithreading sqlite

我正在尝试在多线程C ++程序中使用SQLite 3.7.5。我把它缩小到几行简单的代码:

sqlite3 *Database;
sqlite3_stmt *Stmt;

int retval=sqlite3_open("database.db3",&Database);
retVal=sqlite3_prepare(&Database,"CREATE TABLE RawData (Key CHAR(5))",-1,&Stmt,0);
retval=sqlite3_step(Stmt);
retval=sqlite3_finalize(Stmt);

当我直接从我的主进程调用此代码时,它工作正常。但是,如果我使用CreateThread()来创建一个线程:

unsigned long ThreadId;
CreateThread(0,0,(LPTHREAD_START_ROUTINE) InserterThread,&Info,0,&ThreadId);

我在 sqlite3_step 调用上收到“缓冲区溢出”Visual Studio消息。如果我调试,我看到崩溃位置在dbghook.c的_CRT_DEBUGGER_HOOK中。

我正在使用多线程静态VC库,并使用定义编译:

SQLITE_THREADSAFE=2
THREADSAFE=2

我已使用 sqlite3_threadsafe()进行验证。

我可以跟踪一下SQLite 3代码,但是我希望有人会发现我的代码存在明显的问题,并保存我的聚合。

1 个答案:

答案 0 :(得分:3)

似乎SQLITE_THREADSAFE定义用于编译,它们不会强制库进入行为,只是让它可用。

在启动数据库或运行时,您仍然需要告诉sqlite您需要多线程行为。

  

线程模式的开始时间选择

     

假设编译时线程模式不是单线程,   然后可以在初始化期间使用更改线程模式   sqlite3_config()接口。 SQLITE_CONFIG_SINGLETHREAD动词put   SQLite进入单线程模式,即SQLITE_CONFIG_MULTITHREAD动词   设置多线程模式,以及SQLITE_CONFIG_SERIALIZED动词集   序列化模式。

     

线程模式的运行时选择

     

如果在编译时没有选择单线程模式或   开始时,然后可以创建单个数据库连接   多线程或序列化。不可能降级   单个数据库连接到单线程模式。也不是   如果是,可以升级单个数据库连接   编译时或开始时模式是单线程。

     

确定单个数据库连接的线程模式   通过作为sqlite3_open_v2()的第三个参数给出的标志。该   SQLITE_OPEN_NOMUTEX标志导致数据库连接在   多线程模式和SQLITE_OPEN_FULLMUTEX标志导致   连接处于序列化模式。如果没有指定标志或   如果使用sqlite3_open()或sqlite3_open16()而不是   sqlite3_open_v2(),然后由默认模式确定   使用编译时和开始时设置。

引自http://www.sqlite.org/threadsafe.html