IOS異步和多線程操做&&在sqlite3中的應用

1,數據庫I/O操做(異步)html

數據庫自己是存儲在磁盤上。訪問和修改數據庫,即對磁盤進行讀寫,即I/O操做。sql

磁盤屬於計算機硬件,具備DMA能力,不須要CPU干預,能夠實現異步操做。數據庫

I/O操做通常是消耗時間,sqlite使用異步處理I/O操做。安全

當有多個事務對數據庫進行操做,對應,也會有多個I/O操做。多線程

操做系統將I/O操做,合理放入一個I/O隊列。一次性將隊列內的I/O操做提交給磁盤系統,並行處理多個I/O,提升效率。詳細請看連接,本人也沒有特別深刻研究。併發

2,異步和多線程iphone

異步和多線程,都有能力實現,不阻塞當前線程,使應用更「流暢」。 IOS最多見的, 不阻塞主線程,使UI表現更流暢。異步

二者有區別。 具體請看連接。atom

總之,異步的實現,是基於計算機硬件的支持,而多線程,是操做系統中,一段邏輯代碼控制的。url

3,線程安全以及處理

當一段代碼或者某個變量,被多個線程同時訪問和使用。 這些代碼或者變量,可能會出現非預期的效果,好比數據紊亂和數據安全的問題,這是「非安全的」。

爲了線程安全, 須要在同一時刻,只能有一個線程訪問這些代碼或者變量,IOS中使用「互斥鎖」,來避免這個狀況。

(互斥,mutex,從自己詞語意思:不相容,互相排斥的。數學上,A和B互斥, 指A和B沒有任何交集。 A和B不能同時發生。)

「互斥鎖」即@synchronized(對象A) {} ,對象A,只能被一個線程訪問。

所以,若是使用「互斥鎖」,必定是在, 多個線程,同時訪問一份資源的狀況。

互斥鎖,增長了CPU的開銷。IOS中,atomic,就是爲 setter 方法增長「互斥鎖」。比不要的狀況下,必定要使用「nonatomic」。

4,sqlite3以及sqlite3的多線程

sqlite3是輕量級的數據庫。sqlite3一樣使用異步I/O操做,來讀取數據。關於sqlite3異步I/O操做,具體請看連接

IOS中的sqlite3是線程安全的。IOS中UI在主線程,不阻塞UI線程,保證流暢,因此把sqlite的操做,須要遷移到子線程。這是sqlite3使用多線程的主要驅動力。

有一篇很好的文章,具體點擊連接

  • (1),單線程:禁用全部的mutex鎖,併發使用時會出錯。當SQLite編譯時加了SQLITE_THREADSAFE=0參數,或者在初始化SQLite前調用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)時啓用。
  • (2),多線程:只要一個數據庫鏈接不被多個線程同時使用就是安全的。源碼中是啓用bCoreMutex,禁用bFullMutex。實際上就是禁用數據庫鏈接和prepared statement(準備好的語句)上的鎖,所以不能在多個線程中併發使用同一個數據庫鏈接或prepared statement。當SQLite編譯時加了SQLITE_THREADSAFE=2參數時默認啓用。若SQLITE_THREADSAFE不爲0,能夠在初始化SQLite前,調用sqlite3_config(SQLITE_CONFIG_MULTITHREAD)啓用;或者在建立數據庫鏈接時,設置SQLITE_OPEN_NOMUTEX flag。
  • (3),串行:啓用全部的鎖,包括bCoreMutex和bFullMutex。由於數據庫鏈接和prepared statement都已加鎖,因此多線程使用這些對象時無法併發,也就變成串行了。當SQLite編譯時加了SQLITE_THREADSAFE=1參數時默認啓用。若SQLITE_THREADSAFE不爲0,能夠在初始化SQLite前,調用sqlite3_config(SQLITE_CONFIG_SERIALIZED)啓用;或者在建立數據庫鏈接時,設置SQLITE_OPEN_FULLMUTEX flag。

IOS中的sqlite,默認使用(2)的配置。不方便的是,若是要被另外的線程訪問sqlite,其餘的就必須關閉數據庫鏈接。 代碼中就有不少不方便的地方。

配置(1)不考慮,爲單線程。

配置(3),將多線程變串行方式執行,

(暫停。。)

相關文章
相關標籤/搜索