原標題:SQLite And Multiple Threads
SQLite 支援三種線程模式:
1. 單線程模式
這種模式下,沒有進行互斥,多線程使用不安全
2. 多線程模式
這種模式下,在多線程中使用單個資料庫連接是不安全的,否則就是安全的。(譯註:即不能在多個線程中共用資料庫串連)
3. 串列模式
這種模式下,sqlite是安全執行緒的。(譯註:即使在多個線程中不加互斥的使用同一個資料庫連接)
線程模式可以在編譯時間(通過源碼編譯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()函數來建立資料庫連接,那麼在編譯時間或啟動時指定的線程模式將作為預設的線程模式使用。