通過GCD中的dispatch_barrier_(a)sync加強對sync中所謂等待的理解

首先解釋下標題裏地括號是什麼意思,GCD有個函數叫dispatch_barrier_async,還有個函數叫dispatch_barrier_sync,這個括號只是用來防止標題取得太長…>_<

對於dispatch_barrier_async可能有的朋友沒用過,不知道它是幹嘛的,簡單地介紹一下下,知道的朋友可以跳過此段。 
假設我們原先有6個任務要執行,我們現在要插入一個任務0,這個任務0要在1、2、3都併發執行完了之後才能執行,而4、5、6號任務要在這個任務0結束後才允許併發。大致的意思就跟下面這個圖一樣 
這裏寫圖片描述 
對於這樣一種需求,很多朋友的第一反應就是用個group就解決了。確實如此,但是系統提供了一種更加簡單地方法,那就是dispatch_barrier_async,我們只要按照前面所述的順序將任務分配到隊列就OK,剩下的都不用管了。dispatch_barrier_async的參數跟dispatch_async一模一樣的。

下面開始講正題 
總結前面所說,dispatch_barrier_async是會等待前面提到的任務0結束的,注意這裏是async。說到等待大家必然會想到dispatch_sync,dispatch_sync的任務是串行的,會等待任務結束程序再繼續往下走。那dispatch_barrier是否存在一個sync的方法呢?存在……那麼問題來了……那dispatch_barrier_async和dispatch_barrier_sync的區別在哪呢?如果沒有區別的話蘋果何必搞出2個函數呢,區別必然是有的。

先貼上代碼,代碼非常簡單,就是按照之前提的需求寫的。 
這裏寫圖片描述
barrier裏給了一個比較費時的操作便於看清楚

給的圖裏寫的是dispatch_barrier_sync,因爲我們需要先看看我們熟悉的等待——sync是什麼效果,直接跑起來 
這裏寫圖片描述 
可以看到,確實是1、2、3號任務併發執行完了,然後再執行的我們的0號任務,再併發執行的4、5、6號任務,當然,point3和barrier之間是有明顯停頓的,截圖無法表現。對於這個輸出,應該是意料之中的。截下來,我們來看看async的效果

代碼進行一點點修改,dispatch_barrier_sync改成dispatch_barrier_async。我這裏先把aaa、bbb的輸出隱藏掉。改完代碼可以直接跑起來,我們一起看看結果 
這裏寫圖片描述 
好像除了aaa、bbb之外其它的都跟上面sync的情況一模一樣(當然,併發的順序無法控制),而且point3和barrier之間同樣有明顯停頓,看來,這個dispatch_barrier_async確實會等待它的任務0執行完。

既然這樣那dispatch_barrier_async和dispatch_barrier_sync究竟有什麼區別呢?我們把aaa、bbb的輸出打開看看就知道了。 
這裏寫圖片描述 
區別很明顯,跟sync的情況相比,aaa、bbb的輸出位置完全不同,async的時候aaa的輸出在任務0結束之前,sync的aaa輸出在任務0結束之後。

好了,說到這應該差不多能想通了,我們開始總結 
dispatch_barrier_sync和dispatch_barrier_async的共同點: 
1、都會等待在它前面插入隊列的任務(1、2、3)先執行完 
2、都會等待他們自己的任務(0)執行完再執行後面的任務(4、5、6)

dispatch_barrier_sync和dispatch_barrier_async的不共同點: 
在將任務插入到queue的時候,dispatch_barrier_sync需要等待自己的任務(0)結束之後纔會繼續程序,然後插入被寫在它後面的任務(4、5、6),然後執行後面的任務 
而dispatch_barrier_async將自己的任務(0)插入到queue之後,不會等待自己的任務結束,它會繼續把後面的任務(4、5、6)插入到queue

所以,dispatch_barrier_async的不等待(異步)特性體現在將任務插入隊列的過程,它的等待特性體現在任務真正執行的過程。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章