iOS之线程(二)GCD
1. 概念
- GCD:Gtand Central Dispatch 中樞調度器
- GCD主要解決的是多核并行運算
- GCD是自動管理線程的生命周期的
1.1 任務
- 要執行的操作
- 同步函數:在當前線程中執行任務,不具備開啟新線程的能力,立馬在當前線程繞那個同步執行任務
- 異步函數:可以在新的線程中執行任務,具備開啟新線程的能力
1.2 隊列
- 用來存放任務
- 并發隊列(異步函數才有效)
- 串行隊列
1.3 一般使用情況
- 聲明一個任務
- 將任務添加到隊列中
- GCD會自動將隊列中的任務取出,放到對應的線程中去
- 任務要遵循隊列的FIFO原則,先進先出,后進后出
| 異步函數 | 【1】具備開啟新線程的能力【2】開啟新的線程,任務異步執行 | 【1】具備開啟線程的能力【2】會開線程,開一條線程,隊列中的任務是按照先后順序執行 | 【1】不會開啟新的線程 【2】串行執行 |
| 同步函數 | 【1】不會開啟新的線程【2】串行執行任務 | 【1】不會開啟新的線程【2】串行執行任務 | 【1】如果在主線程中執行會發生死鎖【2】在子線程可以 |
2. 異步函數并發隊列
- 異步函數 :具備開啟新線程的能力
- 異步函數 + 并發隊列 ->開新線程,隊列中的任務是異步執行
注意: 一個隊列中可以.可以添加多個任務,CGD開啟線程是不受控制的,不是說有多少個任務就開啟多少條線程,具體的是系統內部決定的
3. 異步函數 串行隊列
- 異步函數 :具備開啟新線程的能力
- 異步函數 + 串行隊列: 會開線程,開一條線程,隊列中的任務是按照先后順序執行
其實上面的創建的并發隊列,可以換成系統的全局并發隊列,區別:上面是自己手動創建的并發隊列,下面是獲取系統的
//獲取全局并發隊列dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);4. 同步函數+并發隊列
- 同步函數:不具備開啟新線程的能力
- 同步函數+并發隊列:不會開啟子線程,串行執行任務
5. 同步函數+串行隊列
- 同步函數:不具備開啟新線程的能力
- 同步函數+串行隊列:不會開啟新的線程
6.主隊列
- 主隊列是GCD自帶的一種比較特殊的串行隊列
- 在主隊列中的任務,都是在主線程中執行的
- 獲取主隊列 dispatch_get_main_queue()
6.1異步函數+主隊列
- 不會開啟子線程
6.2 同步函數 + 主隊列
- 同步函數:不具備開啟新線程能力,立馬執行,如果這個任務沒有執行完,不會執行下一個任務
- 產生:死鎖
6.3 線程產生死鎖
造成死鎖的條件: 使用同步sync函數 往當前 串行( SERIAL)隊列 添加任務, 會卡住當前任務造成死鎖
線程死鎖
dispatch_sync同步:立馬執行當前線程中的任務,執行完畢才能繼續往下執行
FIFO原則: 先進的先出
意思就是: 整個函數 viewdidload執行完,打印333,才可以執行 同步的任務 打印222, 由于同步函數sync 要立馬執行當前任務,打印222,才可以執行打印333,所以會產生死鎖
原因:
1,創建了一個 子線程
2.隊列0 和 隊列1 都在 子線程中執行
3.由于隊列0 執行到 打印執行任務2時,遇到 同步函數,要立馬執行函數內 隊列1的任務, 此時隊列0的打印任務4 還沒有執行完, 所以要等打印任務4執行完,才可以執行 同步函數 隊列1,造成了線程死鎖
7.線程之間的通信
- 只要是主隊列一定是在主線程執行的
8. GCD任務加強
//任務加強 - (void)demo1{//獲取并發隊列dispatch_queue_t queue = dispatch_get_global_queue(0, 0);//包裝void(^task)(void) = ^{dispatch_sync(queue, ^{NSLog(@"1111---同步--%@",[NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"2222---異步步--%@",[NSThread currentThread]);});dispatch_async(queue, ^{NSLog(@"33333---異步步--%@",[NSThread currentThread]);});};//執行任務dispatch_async(queue, task);}9.柵欄函數
柵欄函數是:保證次函數前面的執行完,然后執行自己的柵欄函數,然后在執行 函數后面的線程
注意:
1.全局并發隊列,對柵欄函數沒有作用
2.使用柵欄函數,必須是自己手動創建的并發隊列
10.同時執行函數 apply
我們知道 for循環是 執行一次循環,在執行下一次循環
有時我們在開發會遇到,多個任務同時執行的問題,比如:同時copy圖片到另外一個文件夾中,此時就會用到 apply同時執行函數
11.CGD 隊列組 - group
- (void)demo1{//創建隊列dispatch_queue_t queue = dispatch_get_global_queue(0, 0);//創建任務組dispatch_group_t group = dispatch_group_create();//異步dispatch_group_async(group, queue, ^{NSLog(@"AAAA");});//異步dispatch_group_async(group, queue, ^{NSLog(@"bbbb");});//異步dispatch_group_async(group, queue, ^{NSLog(@"CCCC");});// 就是保證上面的3個任務 執行完畢 之后才執行 dispatch_group_notify//這個任務組完成的通知dispatch_group_notify(group, queue, ^{NSLog(@"所有的任務完成");});NSLog(@"11111"); }12 .常用的函數
12.1一次性執行函數
//MARK:---一次性執行函數 - (void)testOnce{static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{NSLog(@"執行一次就b在執行了");}); }12.2 常用的代碼執行 延遲操作
//MARK:---延遲執行 - (void)testDiplay{//延遲2l秒執行[self performSelector:@selector(run) withObject:nil afterDelay:2.0];//延遲3秒執行[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(run) userInfo:nil repeats:NO];dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(@"延遲4秒執行");});}- (void)run {NSLog(@"奔跑"); }總結
以上是生活随笔為你收集整理的iOS之线程(二)GCD的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享几个路由器设置小技巧,总有用得到的一
- 下一篇: 区块链是大数据生态圈技术之一_区块链技术