了解GCD
目錄
一、GCD簡介
二、GCD好處
三、GCD任務和隊列
1、任務
同步執行(sync):
異步執行(async):
2、隊列
串行隊列(Serial Dispatch Queue):
并發隊列(Concurrent Dispatch Queue):
四、GCD的使用步驟
1、隊列的創建方法/獲取方法
2、 任務的創建方法
五、GCD的基本使用
1、同步執行 + 并發隊列
2、異步執行 + 并發隊列
3、同步執行 + 串行隊列
4、異步執行 + 串行隊列
5、主隊列
5.1、主隊列 + 異步任務
5.2、主隊列 + 同步任務
六、總結
本文章為作者學習文檔,如有轉載,侵權問題,請自主聯系作者,謝謝。
一、GCD簡介
Grand Central Dispatch(GCD) 是 Apple 開發的一個多核編程的較新的解決方法。它主要用于優化應用程序以支持多核處理器以及其他對稱多處理系統。它是一個在線程池模式的基礎上執行的并發任務。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用
二、GCD好處
- GCD可用于多核并發運算。
- GCD會自動利用更多的CPU內核。
- GCD會自動管理線程的生命周期(創建線程,調度任務,銷毀線程)。
- 程序員只需要告訴GCD想要執行什么任務,不需要編寫任何線程管理代碼。
三、GCD任務和隊列
1、任務
任務:就是執行操作的意思,換句話說就是你在線程中執行的那段代碼。
執行任務的方式有兩種:同步執行(sync)和異步執行(async)。
兩者的主要區別是:是否等待隊列的任務執行結束,以及是否具備開啟新線程的能力。
同步執行(sync):
同步添加任務到指定的隊列中,在添加的任務執行結束之前,會一直等待,直到隊列里面的任務完成之后再繼續執行。
只能在當前線程中執行任務,不具備開啟新線程的能力。
異步執行(async):
異步添加任務到指定的隊列中,它不會做任何等待,可以繼續執行任務。
可以在新的線程中執行任務,具備開啟新線程的能力。
注意:?異步執行(async) 雖然具有開啟新線程的能力,但是并不一定開啟新線程。這跟任務所指定的隊列類型有關。
2、隊列
隊列:這里的隊列指執行任務的等待隊列,即用來存放任務的隊列。隊列是一種特殊的線性表,采用FIFO(先進先出)的原則。
GCD中有兩種隊列:串行隊列和并行隊列。兩者都符合先進先出的原則。
兩者的主要區別是:執行順序不同,以及開啟線程數不用。
串行隊列(Serial Dispatch Queue):
每次只有一個任務被執行。讓任務一個接著一個地執行。(只開啟一個線程,一個任務執行完畢后,再執行下一個任務)
并發隊列(Concurrent Dispatch Queue):
可以讓多個任務并發(同時)執行。(可以開啟多個線程,并且同時執行任務)
注意:?并發隊列 的并發功能只有在異步(dispatch_async)函數下才有效
四、GCD的使用步驟
GCD 的使用步驟其實很簡單,只有兩步。
- 創建一個隊列(串行隊列或并發隊列)
- 將任務追加到任務的等待隊列中,然后系統就會根據任務類型執行任務(同步執行或異步執行)
1、隊列的創建方法/獲取方法
- 可以使用dispatch_queue_create來創建隊列,需要傳入兩個參數,第一個參數表示隊列的唯一標識符,用于 DEBUG,可為空,Dispatch Queue 的名稱推薦使用應用程序 ID 這種逆序全程域名;第二個參數用來識別是串行隊列還是并發隊列。DISPATCH_QUEUE_SERIAL 表示串行隊列,DISPATCH_QUEUE_CONCURRENT 表示并發隊列。
-
對于串行隊列,GCD 提供了的一種特殊的串行隊列:主隊列(Main Dispatch Queue) 。
-
所有放在主隊列中的任務,都會放到主線程中執行。
-
可使用dispatch_get_main_queue()獲得主隊列。
- 對于并發隊列,GCD 默認提供了全局并發隊列(Global Dispatch Queue)。
- 可以使用dispatch_get_global_queue來獲取。需要傳入兩個參數。第一個參數表示隊列優先級,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT。第二個參數暫時沒用,用0即可。
2、 任務的創建方法
GCD 提供了同步執行任務的創建方法dispatch_sync和異步執行任務創建方法dispatch_async。
// 同步執行任務創建方法 dispatch_sync(queue, ^{// 這里放同步執行任務代碼 }); // 異步執行任務創建方法 dispatch_async(queue, ^{// 這里放異步執行任務代碼 });五、GCD的基本使用
| 同步(sync) | 沒有開啟新線程,串行執行任務 | 沒有開啟新線程,串行執行任務 | 沒有開啟新線程,串行執行任務 |
| 異步(async) | 有開啟新線程,并發執行任務 | 有開啟新線程(1條),串行執行任務 | 沒有開啟新線程,串行執行任務 |
1、同步執行 + 并發隊列
代碼如下:
?
結果如下:?
?
根據結果可知:在當前線程中執行任務,不會開啟新線程,執行完一個任務,在執行下一個任務。
2、異步執行 + 并發隊列
代碼如下:
?
?結果如下:
?
根據結果可以得出:除了當前的主線程,系統又開啟了3個線程,并且任務是交替/同時執行的。
3、同步執行 + 串行隊列
代碼如下:
?結果如下:
?
根據結果可以得出:所有任務都是在當前線程中執行,并且沒有開啟新的線程,任務是按照順序執行的,因為是串行隊列,所以每次只有一個任務執行,一個認為完成,然后下一個任務開始。
4、異步執行 + 串行隊列
代碼如下:
結果如下:
?
根據結果可以得出:會開啟新的線程,但是因為任務是串行的,所以執行完一個任務,在執行下一個任務。
5、主隊列
主隊列:是專門負責調度主線程的任務,沒有辦法開辟新的線程。所以,在主隊列下的任務不管是異步任務還是同步任務都不會開辟線程,任務只會在主線程順利執行。
5.1、主隊列 + 異步任務
代碼如下:
?結果如下:
根據結果可以得出:主隊列中放入異步任務,不是馬上執行,而是等到主隊列中的其他不是我們異步添加的任務執行完成之后,才會執行我們異步添加的任務。
?
5.2、主隊列 + 同步任務
主隊列 + 同步任務 在不同的線程中會出現不同的結果,當在主線程中調用,會出現死鎖,而在其他的線程中則不會。
GCD
六、總結
線程和隊列,異步同步函數的關系?
A、一個應用程序表示開啟了一個線程。
B、一個進程至少有一個線程,即至少有一個主線程,也可以開啟多條線程。
C、一個線程中可以有多個隊列,每個隊列中額可以執行多個任務。
D、在線程中執行任務的順序可以是按順序來執行,也可以用不按順序來執行。即表現為串行和并行。
E、那異步和同步函數的作用在哪里?
并行和串行隊列,與異步同步函數的排列組合有如下這些:
1)并行隊列+異步函數:開啟多條線程,不按順序執行任務。
2)串行隊列+異步函數:開啟一條新線程,按順序執行任務。
3)主隊列+異步函數:不開啟新的線程,按順序執行任務。
4)并行隊列+同步函數:不開啟新的線程,按順序執行任務。
5)串行隊列+同步函數:不開啟新的線程,按順序執行任務。
6)主隊列+同步函數:會出現死鎖現象。原因:循環等待,主隊列的東西要等主線程執行完,又不能開線程,所以下面的任務要等上面的任務執行完,然后就卡死了。
總結
- 上一篇: Pycharm远程调试踩坑:[Errno
- 下一篇: 简单操作stm32f10xIO端口配置