国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

iOS 多線程總結(jié)之GCD的使用詳解

2019-10-21 18:44:21
字體:
供稿:網(wǎng)友

進程與線程

進程就是一個應用程序在處理機上的一次執(zhí)行過程,它是一個動態(tài)的概念,而線程是進程中的一部分,進程包含多個線程在運行。

線程是指進程內(nèi)的一個執(zhí)行單元,也是進程內(nèi)的可調(diào)度實體.

與進程的區(qū)別:

(1)地址空間:線程是進程內(nèi)的一個執(zhí)行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
(2)資源擁有:進程是資源分配和擁有的單位,同一個進程內(nèi)的線程共享進程的資源
(3)線程是處理器調(diào)度的基本單位,但進程不是.
(4)二者均可并發(fā)執(zhí)行.

GCD

1.什么是GCD?

全稱是Grand Central Dispatch,可譯為“偉大的中樞調(diào)度器”

純C語言,提供了非常多強大的函數(shù)

2.GCD的優(yōu)勢

GCD是蘋果公司為多核的并行運算提出的解決方案

GCD會自動利用更多的CPU內(nèi)核(比如雙核、四核)

GCD會自動管理線程的生命周期(創(chuàng)建線程、調(diào)度任務、銷毀線程)

程序員只需要告訴GCD想要執(zhí)行什么任務,不需要編寫任何線程管理代碼

隊列與任務

1.隊列主要包含三種:主線程隊列、并行隊列、串行隊列

2.任務主要包含兩種:異步任務和同步任務

多線程執(zhí)行過程就是把任務放在隊列中去執(zhí)行的過程

(在計算機操作系統(tǒng)中對異步和同步有很深入的概念和定義,并影響到計算機系統(tǒng)有單線程到多線程的過渡發(fā)展,其中牽涉到線程切換、時間片等概念。但在GCD這里我們只做大致使用區(qū)別)

隊列:

  1. 并行隊列 :在隊列中的多個任務(線程) 同時執(zhí)行 (不按順序執(zhí)行)
  2. 串行隊列: 在隊列中的多個任務(線程)排隊 依次執(zhí)行(按順序執(zhí)行)

任務:

同步(sync) 和 異步(async) 的主要區(qū)別在于會不會阻塞當前線程,直到 Block 中的任務執(zhí)行完畢!

如果是 同步(sync) 操作,它會阻塞當前線程并等待 Block 中的任務執(zhí)行完畢,然后當前線程才會繼續(xù)往下運行。

如果是 異步(async)操作,當前線程會直接往下執(zhí)行,它不會阻塞當前線程。

3.隊列的創(chuàng)建方法

可以使用dispatch_queue_create來創(chuàng)建對象,需要傳入兩個參數(shù),第一個參數(shù)表示隊列的唯一標識符,用于DEBUG,可為空;第二個參數(shù)用來識別是串行隊列還是并行隊列。DISPATCH_QUEUE_SERIAL表示串行隊列,DISPATCH_QUEUE_CONCURRENT表示并行隊列。

// 串行隊列的創(chuàng)建方法dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);// 并行隊列的創(chuàng)建方法dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);

對于并行隊列,還可以使用dispatch_get_global_queue來創(chuàng)建全局并行隊列。GCD默認提供了全局的并行隊列,需要傳入兩個參數(shù)。第一個參數(shù)表示隊列優(yōu)先級,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT。第二個參數(shù)暫時沒用,用0即可。

4.任務的創(chuàng)建方法

// 同步執(zhí)行任務創(chuàng)建方法dispatch_sync(queue, ^{NSLog(@"%@",[NSThread currentThread]); // 這里放任務代碼});// 異步執(zhí)行任務創(chuàng)建方法dispatch_async(queue, ^{NSLog(@"%@",[NSThread currentThread]); // 這里放任務代碼});

雖然使用GCD只需兩步,但是既然我們有兩種隊列,兩種任務執(zhí)行方式,那么我們就有了四種不同的組合方式。這四種不同的組合方式是

1.并行隊列 + 同步執(zhí)行
2.并行隊列 + 異步執(zhí)行
3.串行隊列 + 同步執(zhí)行
4.串行隊列 + 異步執(zhí)行

5.GCD的基本使用

并行隊列+同步執(zhí)行

不會開啟新線程,執(zhí)行完一個任務,再執(zhí)行下一個任務

-(void) syncConcurrent{NSLog(@"syncConcurrent---begin");dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);dispatch_sync(queue, ^{  for (int i = 0; i < 2; ++i) {    NSLog(@"1------%@",[NSThread currentThread]);  }});dispatch_sync(queue, ^{  for (int i = 0; i < 2; ++i) {    NSLog(@"2------%@",[NSThread currentThread]);  }});dispatch_sync(queue, ^{  for (int i = 0; i < 2; ++i) {    NSLog(@"3------%@",[NSThread currentThread]);  }});NSLog(@"syncConcurrent---end"); }

并行隊列 + 異步執(zhí)行

可同時開啟多線程,任務交替執(zhí)行

- (void) asyncConcurrent{NSLog(@"asyncConcurrent---begin");dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"1------%@",[NSThread currentThread]); }});dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"2------%@",[NSThread currentThread]); }});dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"3------%@",[NSThread currentThread]); }});NSLog(@"asyncConcurrent---end");}

串行隊列 + 同步執(zhí)行

不會開啟新線程,在當前線程執(zhí)行任務。任務是串行的,執(zhí)行完一個任務,再執(zhí)行下一個任務

- (void) syncSerial{NSLog(@"syncSerial---begin");dispatch_queue_t queue = dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"1------%@",[NSThread currentThread]); }});  dispatch_sync(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"2------%@",[NSThread currentThread]); }});dispatch_sync(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"3------%@",[NSThread currentThread]); }});NSLog(@"syncSerial---end");}

串行隊列 + 異步執(zhí)行

會開啟新線程,但是因為任務是串行的,執(zhí)行完一個任務,再執(zhí)行下一個任務

- (void) asyncSerial{NSLog(@"asyncSerial---begin");dispatch_queue_t queue = dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"1------%@",[NSThread currentThread]); }});  dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"2------%@",[NSThread currentThread]); }});dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"3------%@",[NSThread currentThread]); }});NSLog(@"asyncSerial---end");}

主隊列 + 同步執(zhí)行

互等卡住不可行(在主線程中調(diào)用),會出現(xiàn)死鎖

 - (void)syncMain { NSLog(@"syncMain---begin"); dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_sync(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"1------%@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"2------%@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"3------%@",[NSThread currentThread]); } });   NSLog(@"syncMain---end"); }

這是因為我們在主線程中執(zhí)行這段代碼。我們把任務放到了主隊列中,也就是放到了主線程的隊列中。而同步執(zhí)行有個特點,就是對于任務是立馬執(zhí)行的。那么當我們把第一個任務放進主隊列中,它就會立馬執(zhí)行。但是主線程現(xiàn)在正在處理syncMain方法,所以任務需要等syncMain執(zhí)行完才能執(zhí)行。而syncMain執(zhí)行到第一個任務的時候,又要等第一個任務執(zhí)行完才能往下執(zhí)行第二個和第三個任務。

那么,現(xiàn)在的情況就是syncMain方法和第一個任務都在等對方執(zhí)行完畢。這樣大家互相等待,所以就卡住了,所以我們的任務執(zhí)行不了。

主隊列 + 異步執(zhí)行

只在主線程中執(zhí)行任務,執(zhí)行完一個任務,再執(zhí)行下一個任務

- (void)asyncMain{ NSLog(@"asyncMain---begin"); dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"1------%@",[NSThread currentThread]); }});   dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"2------%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i < 2; ++i) {   NSLog(@"3------%@",[NSThread currentThread]); } });  NSLog(@"asyncMain---end"); }

GCD的隊列組 dispatch_group

有時候我們會有這樣的需求:分別異步執(zhí)行2個耗時操作,然后當2個耗時操作都執(zhí)行完畢后再回到主線程執(zhí)行操作。這時候我們可以用到GCD的隊列組。

我們可以先把任務放到隊列中,然后將隊列放入隊列組中。

調(diào)用隊列組的dispatch_group_notify回到主線程執(zhí)行操作。

dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 執(zhí)行1個耗時的異步操作});dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 執(zhí)行1個耗時的異步操作 }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 等前面的異步操作都執(zhí)行完畢后,回到主線程... });

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到IOS開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 多伦县| 巴彦县| 蒙阴县| 望都县| 运城市| 宜良县| 黔南| 壶关县| 溆浦县| 吴桥县| 潮州市| 泽州县| 特克斯县| 辛集市| 吐鲁番市| 平利县| 平潭县| 兴安盟| 定州市| 章丘市| 拉萨市| 讷河市| 天柱县| 炎陵县| 大宁县| 江永县| 民和| 河源市| 台中县| 乃东县| 承德县| 彩票| 扎鲁特旗| 宜春市| 宜丰县| 北流市| 吉林市| 托克逊县| 伊金霍洛旗| 五大连池市| 新化县|