您好,登錄后才能下訂單哦!
如何使用SQLite多線程?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
SQLite支持3種線程模式:
單線程:這種模式下,沒有進行互斥,多線程使用不安全。禁用所有的mutex鎖,并發使用時會出錯。當SQLite編譯時加了SQLITE_THREADSAFE=0參數,或者在初始化SQLite前調用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)時啟用。
多線程:這種模式下,只要一個數據庫連接不被多個線程同時使用就是安全的。源碼中是啟用bCoreMutex,禁用bFullMutex。實際上就是禁用數據庫連接和prepared
statement(準備好的語句)上的鎖,因此不能在多個線程中并發使用同一個數據庫連接或prepared
statement。當SQLite編譯時加了SQLITE_THREADSAFE=2參數時默認啟用。若SQLITE_THREADSAFE不為0,可以在初始化SQLite前,調用sqlite3_config(SQLITE_CONFIG_MULTITHREAD)啟用;或者在創建數據庫連接時,設置SQLITE_OPEN_NOMUTEX
flag。
串行:sqlite是線程安全的。啟用所有的鎖,包括bCoreMutex和bFullMutex
。因為數據庫連接和prepared
statement都已加鎖,所以多線程使用這些對象時沒法并發,也就變成串行了。當SQLite編譯時加了SQLITE_THREADSAFE
=1參數時默認啟用。若SQLITE_THREADSAFE不為0,可以在初始化SQLite前,調用sqlite3_config(SQLITE_CONFIG_SERIALIZED)啟用;或者在創建數據庫連接時,設置SQLITE_OPEN_FULLMUTEX
flag 。
而這里所說的初始化是指調用sqlite3_initialize()函數,這個函數在調用sqlite3_open()時會自動調用,且只有第一次調用是有效的.
為了達到線程安全,SQLite在編譯時必須將 SQLITE_THREADSAFE 預處理宏置為1。在Windows和Linux上, 已編譯的好的二進制發行版中都是這樣設置的。如果不確定你所使用的庫是否是線程安全的,可以調用 sqlite3_threadsafe() 接口找出。調用sqlite3_threadsafe()可以獲得編譯期的SQLITE_THREADSAFE參數 。
也就是說線程模式可以在編譯時(通過源碼編譯sqlite庫時)、啟動時(使用sqlite的應用程序初始化時)或者運行時(創建數據庫連接時)來指定。一般而言,運行時指定的模式將覆蓋啟動時的指定模式,啟動時指定的模式將覆蓋編譯時指定的模式。但是,單線程模式一旦被指定,將無法被覆蓋。默認的線程模式是串行模式。
編譯時選擇線程模式
可以通過定義SQLITE_THREADSAFE宏來指定線程模式。如果沒有指定,默認為串行模式。定義宏SQLITE_THREADSAFE=1指定使用串行模式;=0使用單線程模式;=2使用多線程模式。
sqlite3_threadsafe()函數的返回值可以確定編譯時指定的線程模式。如果指定了單線程模式,函數返回false。如果指定了串行或者多線程模式,函數返回true。由于sqlite3_threadsafe()函數要早于多線程模式以及啟動時和運行時的模式選擇,所以它既不能區別多線程模式和串行模式也不能區別啟動時和運行時的模式。
最后一句可通過sqlite3_threadsafe函數的實現來理解SQLITE_API int
sqlite3_threadsafe(void){ return SQLITE_THREADSAFE;
}如果編譯時指定了單線程模式,那么臨界互斥邏輯在構造時就被省略,因此也就無法在啟動時或運行時指定串行模式或多線程模式。
啟動時選擇線程模式
假如在編譯時沒有指定單線程模式,就可以在應用程序初始化時使用sqlite3_config()函數修改線程模式。參數SQLITE_CONFIG_SINGLETHREAD可指定為
單線程模式,SQLITE_CONFIG_MULTITHREAD指定為多線程模式,SQLITE_CONFIG_SERIALIZED指定為串行模式。
運行時選擇線程模式
如果沒有在編譯時和啟動時指定為單線程模式,那么每個數據庫連接在創建時可單獨的被指定為多線程模式或者串行模式,但是不能指定為單線程模式。如果在編譯時或啟動時指定為單線程模式,就無法在創建連接時指定多線程或者串行模式。
創建連接時用sqlite3_open_v2()函數的第三個參數來指定線程模式。SQLITE_OPEN_NOMUTEX標識創建多線程模式的連接;SQLITE_OPEN_FULLMUTEX標識創建串行模式的連接。如果沒有指定標識,或者使用sqlite3_open()或sqlite3_open16()函數來創建數據庫連接,那么在編譯時或啟動時指定的線程模式將作為默認的線程模式使用。
看完上述內容,你們掌握如何使用SQLite多線程的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。