ReactiveSwift源碼解析(十一) Atomic的代碼實現以及其中的Defer延遲、Posix互斥鎖、遞歸鎖

本篇博客咱們來聊一下ReactiveSwift中的原子性操做,在此內容上咱們簡單的聊一下Posix互斥鎖以及遞歸鎖的概念以及使用場景。而後再聊一下Atomic的代碼實現Atomic主要負責多線程下的原子操做,負責共享資源的同步一致性。而在Atomic中就是使用到了Posix互斥鎖和遞歸鎖。在聊上述內容以前,咱們先來回顧一下Swift語言中延遲執行defer的使用方式,在以前Swift編程的相關博客中也涉及到了defer的使用方式。defer由於Atomic使用到了延遲操做,因此下方咱們再作一個defer的簡單回顧。git

 

1、Defer延遲執行github

在本篇博客之因此聊defer延遲執行,是由於在Atomic的代碼實現中,使用了defer{}來爲操做加的鎖。具體的說是在操做前進行加鎖,而後緊接着使用defer{}進行解鎖,稍後咱們會進行介紹。Swift中的Defer延遲執行是比較經常使用的,其用法也是比較簡單的。下方就是咱們列舉了一個示例,該示例比較簡單。首先咱們輸出a,而後使用defer塊執行輸出b的語句,而後就是輸出c,最後是使用defer塊輸出d,具體代碼以下。編程

  

 

在看上述代碼輸出結果時,咱們能夠先預測一下輸出結果,是輸出「abcd」仍是「acbc」仍是「acdb」呢?下方就是上述代碼片斷的輸出結果。從下方代碼片斷中咱們不難看出,其結果爲「acdb」。從結果中咱們不難看出defer{}塊的執行順序是在該做用域結束以前從後往前執行。swift

  

 

根據上述代碼片斷以及輸出結果,咱們能夠畫出下方這個運行簡圖,以下所示。由於下方這個簡圖並不複雜,在此就不作過多贅述了。多線程

  

 

2、Posix互斥鎖框架

互斥鎖的概念就不作過多贅述了,簡單的說就是防止多個線程同時修改一塊共享區域,致使數據不一樣步的狀況發生而添加的鎖。互斥鎖的互斥是線程的互斥,也就是說添加互斥鎖的代碼塊在同一個時間點上只容許一個線程對這塊共享區域進行操做,其餘線程若想對該塊區域進行操做的話,須要等待以前的互斥鎖打開後方可進入。函數

下方這個PosixThreadMutex類是Atomic的代碼實現中封裝的Posix互斥鎖。在該代碼實現中主要調用了C語言中的線程互斥鎖的相關函數。下方鎖的使用方式,稍後再聊Atomic類的時候會使用到下方的這個互斥鎖。spa

  

 

3、遞歸鎖線程

接下來咱們來看一下遞歸鎖,在Atomic的代碼實現中也使用到了遞歸鎖。「遞歸鎖」顧名思義就是在遞歸中使用的鎖,普通鎖在一個線程中是不能被重用的,也就是說一個普通鎖被上鎖後,你就不能再次調用上鎖的方法了,這樣會出問題的。等普通鎖被解鎖後,你才能夠對其進行上鎖。針對普通鎖的不可重用性,咱們給出了下方示例,以下所示。blog

  

 

上述代碼片斷比較簡單,對普通鎖連續執行了兩次lock,而後執行咱們的代碼塊,以後就是執行了兩次unlock。該代碼使用普通鎖的步驟實際上是與遞歸函數中使用普通鎖的場景是同樣的。當遞歸實現函數是,執行第一次遞歸時,添加了一個普通鎖,在鎖未打開時,第二次遞歸時又會執行一下上鎖。這種場景與上述代碼片斷是同樣的。由於普通鎖在同一個線程中的不可重用性,因此上述代碼會產生死鎖DeadLock。下方截圖就是上述代碼片斷所執行的結果: 

  

 

咱們將上述代碼中的NSLock普通鎖修改爲NSRecursiveLock遞歸鎖後,以下。下方的代碼就能夠正確執行。由於遞歸鎖能夠在同一個線程中重複的使用。具體以下所示:

  

 

既然是遞歸鎖,那麼接下來咱們就在遞歸函數中來使用一下遞歸鎖。在遞歸函數執行使用鎖時,本質上是屢次使用一個鎖。也就是在一個鎖未上鎖時再次對其上鎖。下方就是遞歸鎖在遞歸函數中使用的簡單示例。

  

 

4、Atomic原子操做的具體代碼實現

聊完互斥鎖和遞歸鎖後,接下來咱們來看一下ReactiveSwift中的原子操做Atomic類的具體代碼實現。Aotmic中使用了上述咱們聊的Posix互斥鎖來進行的原子操做。下方就是Atomic類的代碼實現。

從下方代碼片斷中咱們不難看出,在value讀取和修改時都會進行加鎖和解鎖操做。固然,解鎖的代碼是放在defer{}的語句塊中進行操做的。在Atomic.swift文件中還有一個RecursiveAtomic類,也就是負責遞歸原子操做的。RecursiveAtomicAtomic類的不一樣之處在於前者使用的是遞歸鎖,負責在遞歸操做時保持原子操做。然後者使用的是互斥鎖。RecursiveAtomic的代碼與Atomic類的代碼相似,在此就不作過多贅述了。

  

 

今天的博客就先到這兒,下篇博客咱們會繼續解析ReactiveSwift框架中的其餘內容。

上述代碼github分享地址:https://github.com/lizelu/TipSwiftForRac  

相關文章
相關標籤/搜索