2012-01-20 185 views
4

我想在一個多線程的C++程序使用SQLite 3.7.5。我已經縮小到一些簡單的代碼行:多線程的SQLite崩潰

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碼,但我希望一些人會發現一個明顯的問題,我的代碼並保存我aggrevation。

+0

引用如果你已經解決了這個問題,請發表與其他解決方案的答覆。 – chacham15

+0

我從來沒有找到問題的真正原因。我想我最終把項目減少到了最低限度,問題就消失了。然後,我逐漸添加了組件,發現我最終會找到觸發問題的組件,但我設法添加了所有組件,而不會出現問題重建。所以這是一個謎... –

回答

3

看來,SQLITE_THREADSAFE定義是用於編譯,他們並不庫強迫行爲,只是使它提供。

你還是要告訴你要多線程行爲sqlite的,或者當您啓動數據庫或運行期間。

的穿線模式

啓動時間選擇假設編譯時的線程模式不是單一線程, 然後穿線模式可以使用 sqlite3_config()接口初始化期間改變。 SQLITE_CONFIG_SINGLETHREAD動詞將 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

+0

沒有運氣。我試過sqlite3_config(SQLITE_CONFIG_MULTITHREAD);並使用sqlite3_open_v2和SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX。同樣的問題。 –

+0

我自此編碼了一個獨立版本的問題,但沒有看到問題。這是一個相當大的項目,我將不得不逐漸添加組件,直到問題重新出現。不管怎麼說,還是要謝謝你。 –