GCD 你應(yīng)該知道的...

一痹屹、定義與實(shí)現(xiàn)

放在最前:文章為本人學(xué)習(xí)隨筆章郁,若對您有幫助,不勝榮幸;若有錯漏歡迎評論區(qū)留言暖庄。

GCD 是一套異步執(zhí)行任務(wù)的技術(shù)之一聊替,是基于系統(tǒng)級的核心XNU內(nèi)核級上實(shí)現(xiàn)的,所以在iOS 開發(fā)中其性能是其他多線程技術(shù)無法與之相媲美的培廓。

那么GCD是如何實(shí)現(xiàn)的呢

GCD 的API全部為包含在libdispatch庫中的C語言函數(shù)惹悄。Dispatch Queue 通過結(jié)構(gòu)體和鏈表,被實(shí)現(xiàn)FIFO隊列肩钠。Pthread_workqueue是包含再Libc提供的pthreads API 中泣港。XNU內(nèi)核提供的workqueue 內(nèi)核持有的4中優(yōu)先級別的queue 與Dispatch Queue的優(yōu)先級類似,三個組件對應(yīng)優(yōu)先級關(guān)系如下圖:


二价匠、GCD 常用的 API

開發(fā)過程中我們要做的就是把定義好要執(zhí)行的任務(wù)并寫在block中并添加到適合的Dispatch Queue中当纱。

首先明確 Serial Dispatch Queue 和 Concurrent Dispatch Queue 的區(qū)別,前者是等待現(xiàn)在執(zhí)行中的任務(wù)處理結(jié)束即為串行隊列踩窖,后者是指不等待現(xiàn)在執(zhí)行中處理結(jié)束即為并行隊列坡氯;那么如何創(chuàng)建隊列呢如下:

/// 分別創(chuàng)建一個串行隊列與并發(fā)隊列

dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.dr", DISPATCH_QUEUE_SERIAL);

dispatch_queue_t concurrentQueue = dispatch_queue_create("com.gcd.dr", DISPATCH_QUEUE_CONCURRENT);

創(chuàng)建好隊列以后就是怎么把任務(wù)添加到隊列里啦,那么追加任務(wù)又有兩種方式:同步執(zhí)行 dispatch_sync 和 異步執(zhí)行 dispatch_async 洋腮。如下示例:

? ?dispatch_async(serialQueue, ^{

? ? ? ? NSLog(@"打印1");

? ? });

這句是表示將打印任務(wù)非同步的追加到串行隊列中箫柳,不需要等待上一次任務(wù)執(zhí)行結(jié)束。

dispatch_sync(serialQueue,?^{

? ? ? ? NSLog(@"打印2");

? ? });

這句則是同步添加啥供,一旦調(diào)用同步那么會在打印2結(jié)束之后才能返回悯恍,但使用同步則要注意死鎖的情況 。

dispatch_queue_t queue=dispatch_get_main_queue();

dispatch_async(queue,^{

? ? dispatch_sync(queue,^{NSLog(@"Hello?");});

});

在主線程中執(zhí)行指定的Block等待Main Dispatch Queue 中要執(zhí)行的Block 執(zhí)行結(jié)束伙狐。

兩種特殊隊列

主隊列 Main Dispatch Queue / 全局隊列 Global Dispatch Queue

主隊列的執(zhí)行是在主線程的RunLoop 中執(zhí)行

全局隊列則是并行隊列涮毫,其有4個優(yōu)先級別:高、默認(rèn)鳞骤、低、后臺黍判。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)^{

? ? //全局隊列里執(zhí)行 數(shù)據(jù)計算類操作

? ? dispatch_async(dispatch_get_main_queue(),^{

? ? //主線程刷新UI操作

});

})

dispatch_set_target_queue

用于設(shè)定任務(wù)執(zhí)行優(yōu)先級

dispatch_queue_t globalBackGroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

dispatch_set_target_queue(serialQueue,globalBackGroundQueue);

第一個參數(shù)為要執(zhí)行的隊列豫尽;但第一個參數(shù)不建議使用主隊列或者全局隊列

dispatch_after?

延時處理線程

Dispatch Group

dispatch_queue_t firstQueue = dispatch_queue_create("first.com", DISPATCH_QUEUE_CONCURRENT);

? ? dispatch_queue_t secondQueue = dispatch_queue_create("second.com", DISPATCH_QUEUE_CONCURRENT);

? ? dispatch_group_t group = dispatch_group_create();

? ? dispatch_group_notify(group, firstQueue, ^{

? ? ? ? NSLog(@"任務(wù)組處理完成調(diào)用 %@",[NSThreadcurrentThread]);

? ? });

? ? dispatch_group_async(group, firstQueue, ^{

? ? ? ? NSLog(@"吃");

? ? });

? ? dispatch_group_async(group, secondQueue, ^{

? ? ? ? NSLog(@"吃");

? ? });

dispatch_barrier_async 柵欄

dispatch_async(concurrentQueue, ^{

? ? ? ? NSLog(@"1---%@",[NSThread currentThread]);? ? ? // 打印當(dāng)前線程

? ? });

? ? dispatch_barrier_async(concurrentQueue, ^{

? ? ? ? NSLog(@"barrier---%@",[NSThread currentThread]);// 打印當(dāng)前線程

? ? });

?? ?dispatch_async(concurrentQueue, ^{

? ? ? ? NSLog(@"2---%@",[NSThread currentThread]);? ? ? // 打印當(dāng)前線程

? ? });

dispatch_apply

按指定次數(shù)執(zhí)行任務(wù)的次數(shù)的意思

?? ?dispatch_apply(10,concurrentQueue,^(size_tindex){

? ? ? ? NSLog(@"%@zu",index); ? ?});

? ? NSLog(@"done");

dispatch_suspend / dispatch_resume

任務(wù)的掛起與恢復(fù)

? ? dispatch_async(concurrentQueue,^{

? ? ? ? NSLog(@"1234");

? ? });

? ? dispatch_suspend(concurrentQueue);

? ? NSLog(@"暫停");

? ? dispatch_resume(concurrentQueue);

? ? NSLog(@"恢復(fù)");

Dispatch Semaphore

首先明確線程安全概念:如果你的代碼所在的進(jìn)程中有多個線程在同時運(yùn)行,而這些線程可能會同時運(yùn)行這段代碼顷帖。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的美旧,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的贬墩。

使用 semaphore 加鎖?dispatch_semaphore_wait 函數(shù)返回為0時刻安全第執(zhí)行需要排他控制的處理榴嗅。該處理結(jié)束時通過將其計數(shù)加1

?dispatch_semaphore_t semaphore =dispatch_semaphore_create(1);

? ? NSMutableArray *array=[NSMutableArray array];

? ? for(inti=0;i<1000;i++)

? ? {

? ? ? ? dispatch_async(concurrentQueue, ^{

? ? ? ? ? ? dispatch_set_context(semaphore,DISPATCH_TIME_FOREVER);

? ? ? ? ? ? [array addObject:@(i)];

? ? ? ? ? ? dispatch_semaphore_signal(semaphore);

? ? ? ? });

? ? }

dispatch_once

只執(zhí)行一次,常用于單例的生成

- (void)once {

? ? static dispatch_once_t onceToken;

? ? dispatch_once(&onceToken, ^{

? ? ? ? // 只執(zhí)行 1 次的代碼(這里面默認(rèn)是線程安全的)

? ? });}

Dispatch I/O

通過該方法讀寫文件陶舞,詳細(xì)??請見:http://www.reibang.com/p/33d6f52fe26b

更多api 請見 apple 官方文檔:https://developer.apple.com/documentation/dispatch?language=objc

參考:

1嗽测、http://www.reibang.com/p/2d57c72016c6

2、http://www.reibang.com/p/216228e153b0

3、<<Object-C 高級編程iOS 與OSX 多線程和內(nèi)存管理>>


那么GCD是如何實(shí)現(xiàn)的呢

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末唠粥,一起剝皮案震驚了整個濱河市疏魏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晤愧,老刑警劉巖大莫,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異官份,居然都是意外死亡只厘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門舅巷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羔味,“玉大人,你說我怎么就攤上這事悄谐〗槠溃” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵爬舰,是天一觀的道長们陆。 經(jīng)常有香客問我,道長情屹,這世上最難降的妖魔是什么坪仇? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮垃你,結(jié)果婚禮上椅文,老公的妹妹穿的比我還像新娘。我一直安慰自己惜颇,他們只是感情好皆刺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凌摄,像睡著了一般羡蛾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锨亏,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天痴怨,我揣著相機(jī)與錄音,去河邊找鬼器予。 笑死浪藻,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乾翔。 我是一名探鬼主播爱葵,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钧惧?” 一聲冷哼從身側(cè)響起暇韧,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浓瞪,沒想到半個月后懈玻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乾颁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年涂乌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片英岭。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡湾盒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诅妹,到底是詐尸還是另有隱情罚勾,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布吭狡,位于F島的核電站尖殃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏划煮。R本人自食惡果不足惜送丰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弛秋。 院中可真熱鬧器躏,春花似錦、人聲如沸蟹略。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挖炬。三九已至揽浙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茅茂,已是汗流浹背捏萍。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工太抓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留空闲,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓走敌,卻偏偏與公主長得像碴倾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348