我正在尝试在多线程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代码,但是我希望有人会发现我的代码存在明显的问题,并保存我的聚合。
答案 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(),然后由默认模式确定 使用编译时和开始时设置。