Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-Threaded SQLite Crash

I'm trying to use SQLite 3.7.5 in a multi-threaded C++ program. I've narrowed it down to a few simple lines of code:

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);

When I call this code directly from my main process, it works fine. However, if I use CreateThread() to create a thread:

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

I get a "buffer overrun" Visual Studio message on the sqlite3_step call. If I debug, I see the crash location is in _CRT_DEBUGGER_HOOK in dbghook.c.

I'm using the Multi-threaded Static VC libraries, and am compiling with the defines:

SQLITE_THREADSAFE=2
THREADSAFE=2

I have verified with sqlite3_threadsafe().

I can trace a bit into the SQLite 3 code, but I'm hoping some one will spot an obvious problem with my code and save me the aggrevation.

like image 235
Marc Bernier Avatar asked Jan 20 '12 22:01

Marc Bernier


People also ask

Does SQLite support multithreading?

In serialized mode, SQLite can be safely used by multiple threads with no restriction.

How many concurrent connections can SQLite handle?

The ATTACH statement is an SQLite extension that allows two or more databases to be associated to the same database connection and to operate as if they were a single database. The number of simultaneously attached databases is limited to SQLITE_MAX_ATTACHED which is set to 10 by default.

How much traffic can SQLite handle?

The amount of web traffic that SQLite can handle depends on how heavily the website uses its database. Generally speaking, any site that gets fewer than 100K hits/day should work fine with SQLite. The 100K hits/day figure is a conservative estimate, not a hard upper bound.

Is SQLite database thread safe?

Session objects are not thread-safe. In fact, session objects are thread-bound. The {@link SQLiteDatabase} uses a thread-local variable to associate a session with each thread for the use of that thread alone.


1 Answers

It appears that the SQLITE_THREADSAFE define is for compiling, they don't force the library into the behavior, just make it available.

You still have to tell sqlite that you want multi-threaded behavior, either when you start up the database or during runtime.

Start-time selection of threading mode

Assuming that the compile-time threading mode is not single-thread, then the threading mode can be changed during initialization using the sqlite3_config() interface. The SQLITE_CONFIG_SINGLETHREAD verb puts SQLite into single-thread mode, the SQLITE_CONFIG_MULTITHREAD verb sets multi-thread mode, and the SQLITE_CONFIG_SERIALIZED verb sets serialized mode.

Run-time selection of threading mode

If single-thread mode has not been selected at compile-time or start-time, then individual database connections can be created as either multi-thread or serialized. It is not possible to downgrade an individual database connection to single-thread mode. Nor is it possible to escalate an individual database connection if the compile-time or start-time mode is single-thread.

The threading mode for an individual database connection is determined by flags given as the third argument to sqlite3_open_v2(). The SQLITE_OPEN_NOMUTEX flag causes the database connection to be in the multi-thread mode and the SQLITE_OPEN_FULLMUTEX flag causes the connection to be in serialized mode. If neither flag is specified or if sqlite3_open() or sqlite3_open16() are used instead of sqlite3_open_v2(), then the default mode determined by the compile-time and start-time settings is used.

Referenced from http://www.sqlite.org/threadsafe.html

like image 86
Tom Kerr Avatar answered Sep 20 '22 23:09

Tom Kerr