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