http://www.cocoachina.com/ios/20170707/19769.html
http://www.cocoachina.com/ios/20170829/20404.html
https://www.cnblogs.com/wendingding/p/3806821.html
https://www.cnblogs.com/wendingding/tag/多線程篇/
1. dispatch_after
該函數(shù)用于任務(wù)延時(shí)執(zhí)行械姻,其中參數(shù)dispatch_time_t代表延時(shí)時(shí)長,dispatch_queue_t代表使用哪個(gè)隊(duì)列机断。如果隊(duì)列未主隊(duì)列楷拳,那么任務(wù)在主線程執(zhí)行,如果隊(duì)列為全局隊(duì)列或者自己創(chuàng)建的隊(duì)列吏奸,那么任務(wù)在子線程執(zhí)行欢揖,代碼如下:
-(void)GCDDelay{
????//主隊(duì)列延時(shí)
????dispatch_time_t?when_main?=?dispatch_time(DISPATCH_TIME_NOW,?(int64_t)(3.0?*?NSEC_PER_SEC));
????dispatch_after(when_main,?dispatch_get_main_queue(),?^{
????????NSLog(@"main_%@",[NSThread?currentThread]);
????});
????//全局隊(duì)列延時(shí)
????dispatch_time_t?when_global?=?dispatch_time(DISPATCH_TIME_NOW,?(int64_t)(4.0?*?NSEC_PER_SEC));
????dispatch_after(when_global,?dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,?0),?^{
????????NSLog(@"global_%@",[NSThread?currentThread]);
????});
????//自定義隊(duì)列延時(shí)
????dispatch_time_t?when_custom?=?dispatch_time(DISPATCH_TIME_NOW,?(int64_t)(5.0?*?NSEC_PER_SEC));
????dispatch_after(when_custom,?self.serialQueue,?^{
????????NSLog(@"custom_%@",[NSThread?currentThread]);
????});
}
2. dispatch_once
保證函數(shù)在整個(gè)生命周期內(nèi)只會(huì)執(zhí)行一次,看代碼奋蔚。
-(void)touchesBegan:(NSSet?*)touches?withEvent:(UIEvent?*)event{
????static?dispatch_once_t?onceToken;
????dispatch_once(&onceToken,?^{
????????NSLog(@"%@",[NSThread?currentThread]);
????});
}
3. dispatch_group_async & dispatch_group_notify
4. dispatch_barrier_async
柵欄函數(shù)她混,這么看來它能擋住或者分隔什么東西,別瞎猜了泊碑,反正你又猜不對(duì)坤按,看這,使用此方法創(chuàng)建的任務(wù)馒过,會(huì)查找當(dāng)前隊(duì)列中有沒有其他任務(wù)要執(zhí)行臭脓,如果有,則等待已有任務(wù)執(zhí)行完畢后再執(zhí)行腹忽,同時(shí)谢鹊,在此任務(wù)之后進(jìn)入隊(duì)列的任務(wù),需要等待此任務(wù)執(zhí)行完成后留凭,才能執(zhí)行。
5. dispatch_apply
該函數(shù)用于重復(fù)執(zhí)行某個(gè)任務(wù)偎巢,如果任務(wù)隊(duì)列是并行隊(duì)列蔼夜,重復(fù)執(zhí)行的任務(wù)會(huì)并發(fā)執(zhí)行,如果任務(wù)隊(duì)列為串行隊(duì)列压昼,則任務(wù)會(huì)順序執(zhí)行求冷,需要注意的是,該函數(shù)為同步函數(shù)窍霞,要防止線程阻塞和死鎖哦
6. dispatch_semaphore_create & dispatch_semaphore_signal & dispatch_semaphore_wait
看這幾個(gè)函數(shù)的時(shí)候你需要拋開隊(duì)列匠题,丟掉同步異步,不要把它們想到一起但金,混為一談韭山,信號(hào)量只是控制任務(wù)執(zhí)行的一個(gè)條件而已,相對(duì)于上面通過隊(duì)列以及執(zhí)行方式來控制線程的開辟和任務(wù)的執(zhí)行,它更貼近對(duì)于任務(wù)直接的控制钱磅。類似于單個(gè)隊(duì)列的最大并發(fā)數(shù)的控制機(jī)制梦裂,提高并行效率的同時(shí),也防止太多線程的開辟對(duì)CPU早層負(fù)面的效率負(fù)擔(dān)盖淡。
dispatch_semaphore_create創(chuàng)建信號(hào)量年柠,初始值不能小于0;
dispatch_semaphore_wait等待降低信號(hào)量褪迟,也就是信號(hào)量-1冗恨;
dispatch_semaphore_signal提高信號(hào)量,也就是信號(hào)量+1味赃;
dispatch_semaphore_wait和dispatch_semaphore_signal通常配對(duì)使用掀抹。
總結(jié)
1. 對(duì)于單核CPU來說,不存在真正意義上的并行洁桌,所以渴丸,多線程執(zhí)行任務(wù),其實(shí)也只是一個(gè)人在干活另凌,CPU的調(diào)度決定了非等待任務(wù)的執(zhí)行速率谱轨,同時(shí)對(duì)于非等待任務(wù),多線程并沒有真正意義提高效率吠谢。
2. 線程可以簡單的認(rèn)為就是一段代碼+運(yùn)行時(shí)數(shù)據(jù)土童。
3. 同步執(zhí)行會(huì)在當(dāng)前線程執(zhí)行任務(wù),不具備開辟線程的能力或者說沒有必要開辟新的線程工坊。并且献汗,同步執(zhí)行必須等到Block函數(shù)執(zhí)行完畢,dispatch函數(shù)才會(huì)返回王污,從而阻塞同一串行隊(duì)列中外部方法的執(zhí)行罢吃。
4. 異步執(zhí)行dispatch函數(shù)會(huì)直接返回,Block函數(shù)我們可以認(rèn)為它會(huì)在下一幀加入隊(duì)列昭齐,并根據(jù)所在隊(duì)列目前的任務(wù)情況無限下一幀執(zhí)行尿招,從而不會(huì)阻塞當(dāng)前外部任務(wù)的執(zhí)行。同時(shí)阱驾,只有異步執(zhí)行才有開辟新線程的必要就谜,但是異步執(zhí)行不一定會(huì)開辟新線程。
5. 只要是隊(duì)列里覆,肯定是FIFO(先進(jìn)先出)丧荐,但是誰先執(zhí)行完要看第1條。
6. 只要是串行隊(duì)列喧枷,肯定要等上一個(gè)任務(wù)執(zhí)行完成虹统,才能開始下一個(gè)任務(wù)弓坞。但是并行隊(duì)列當(dāng)上一個(gè)任務(wù)開始執(zhí)行后,下一個(gè)任務(wù)就可以開始執(zhí)行窟却。
7. 想要開辟新線程必須讓任務(wù)在異步執(zhí)行昼丑,想要開辟多個(gè)線程,只有讓任務(wù)在并行隊(duì)列中異步執(zhí)行才可以夸赫。執(zhí)行方式和隊(duì)列類型多層組合在一定程度上能夠?qū)崿F(xiàn)對(duì)于代碼執(zhí)行順序的調(diào)度菩帝。
8. 同步+串行:未開辟新線程,串行執(zhí)行任務(wù)茬腿;同步+并行:未開辟新線程呼奢,串行執(zhí)行任務(wù);異步+串行:新開辟一條線程切平,串行執(zhí)行任務(wù)握础;異步+并行:開辟多條新線程,并行執(zhí)行任務(wù)悴品;在主線程中同步使用主隊(duì)列執(zhí)行任務(wù)禀综,會(huì)造成死鎖。
8. 對(duì)于多核CPU來說苔严,線程數(shù)量也不能無限開辟定枷,線程的開辟同樣會(huì)消耗資源,過多線程同時(shí)處理任務(wù)并不是你想像中的人多力量大届氢。