細說GCD

GCD是多線程編程中很常用的技術,同時,作為一項重要的知識點,在面試中也是“常來之客”,本文通過API進行GCD的歸納和總結


GCD之前

在蘋果引入GCD技術之前,Cocoa框架中的NSObject類提供了performSelectorInBackground:withObjectperformSelectorOnMainThread等來實現(xiàn)多線程編程,此外還有NSThread、NSOperation等,伴隨GCD的誕生,NSOperation也進行重寫,基于GCD實現(xiàn)

關于多線程編程

一個CPU一次只能執(zhí)行一個命令,這樣連續(xù)執(zhí)行命令,相當于一條無分叉的路徑,這樣的路徑就是“線程”。OS和iOS的核心XNU內(nèi)核在進行操作系統(tǒng)事件處理的時候,會切換執(zhí)行路徑。每條執(zhí)行路徑的狀態(tài),會保存到每條路徑專用的內(nèi)存塊中,便于下次執(zhí)行時復原信息。這種來回切換的操作可以被稱為“上下文切換”,也正是這種切換產(chǎn)生了多線程。

多線程需要注意的問題

  • 數(shù)據(jù)不一致:例如,兩個線程同時更新一個數(shù)據(jù)
  • 死鎖:兩個線程互相等待對方執(zhí)行結束
  • 內(nèi)存消耗:線程過多會消耗大量內(nèi)存
    ...

GCD的API

dispatch_queue_t

分為兩種

  • Serial Dispatch Queue:串行隊列
    • 系統(tǒng)提供的dispatch_get_main_queue
    • 自定義創(chuàng)建dispatch_queue_create("name", DISPATCH_QUEUE_SERIAL)其中的name是該queue的名字
  • Concurrent Dispatch Queue:并行隊列
    • 系統(tǒng)提供的dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)其中第一個參數(shù)有四種,對應不同優(yōu)先級
      • DISPATCH_QUEUE_PRIORITY_BACKGROUND
      • DISPATCH_QUEUE_PRIORITY_LOW
      • DISPATCH_QUEUE_PRIORITY_DEFAULT
      • DISPATCH_QUEUE_PRIORITY_HIGH
    • 自定義創(chuàng)建dispatch_queue_create("name",DISPATCH_QUEUE_CONCURRENT)

dispatch_set_target_queue

  • dispatch_queue_create生成的dispatch_queue_t的優(yōu)先級都是默認優(yōu)先級,如果想要改變優(yōu)先級可以使用:
dispatch_queue_t queue1 = dispatch_queue_create("name", DISPATCH_QUQUE_SERIAL);
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND);
dispatch_set_target_queue(queue1, queue2);
  • 同時如果將多個串行隊列的目標制定為同一個串行隊列,那么本應該并行執(zhí)行的各個串行隊列只能串行地進行執(zhí)行

dispatch_after

在指定時間之后執(zhí)行處理,本質(zhì)上是在指定時間之后將任務追加到隊列中

dispatch_group_t

隊列組可以用來實現(xiàn):當所有處理結束之后,執(zhí)行一個操作。正常來說使用串行隊列是很容易實現(xiàn)的,但是如果是并行隊列的話,想要實現(xiàn)這個操作,就需要借助隊列組來實現(xiàn)

dispatch_group_notify

  • 用于group中所有任務執(zhí)行完之后追加一個操作執(zhí)行
  • 該方法不會阻塞當前線程

dispatch_group_wait

long result = dispatch_group_wait(group, time);
  • 該函數(shù)會阻塞當前線程(即代碼所處的線程)
  • time的選擇
    • 可以是一個固定的時間,如果超時了,該函數(shù)就會返回
    • 也可以是DISPATCH_TIME_FOREVER,表示一直等待,直到group中所有操作執(zhí)行完畢,函數(shù)才返回。
  • 返回值
    • 0:代表group中的任務全部執(zhí)行完了
    • 非0:代表超時了

dispatch_barrier_async

一般來說,關于數(shù)據(jù)庫的操作,使用串行隊列能夠避免數(shù)據(jù)異常的問題。但是實際上,讀取操作之間是沒有影響的,為了提高效率,讀取操作通過是并行的,只需要保證寫操作的時候,沒有任何一個讀取操作在進行即可。

dispatch_async(queue, block_reading1);
dispatch_async(queue, block_reading2);
dispatch_barrier_async(queue, block_writing);
dispatch_async(queue, block_reading3);
dispatch_async(queue, block_reading4);

以上代碼中的寫操作,會等待上面代碼中的讀操作(已經(jīng)被添加到隊列中的任務)執(zhí)行完畢之后,開始執(zhí)行,此時,寫操作以下的代碼中的讀操作需要的等待寫操作執(zhí)行完之后才能添加到隊列中執(zhí)行

dispatch_async和dispatch_sync

  • dispatch_async是異步執(zhí)行,代表不會阻塞當前線程,會另外開辟線程執(zhí)行任務
  • dispatch_sync是同步執(zhí)行,代表會阻塞當前線程,會在當前線程執(zhí)行任務

dispatch_apply

該函數(shù)可以將block中的任務指定次數(shù)加入到隊列中,并且會阻塞當前線程,直到所有的任務全部執(zhí)行完

dispatch_suspend和dispatch_resume

  • dispatch_suspend:掛起后,添加到隊列中的任務,尚未執(zhí)行的處理都會停止執(zhí)行
  • dispatch_resume:將會恢復以上操作

dispatch_semaphore_t

GCD中的信號量,用于控制并行執(zhí)行,在GCD中,控制并行可以通串行隊列和dispatch_barrier_async來做,而信號量semaphore可以更加精確地控制并行

  • dispatch_semaphore_create(number ):number為信號量的初始量
  • dispatch_semaphore_wait(semaphore, time)
    • 其中time和group中是一樣的
    • 返回值:
      • 0:如果信號量大于等于1,返回0,同時將信息號量減去1
      • 非0:超過指定時間(同時這時信號量為0)
  • dispatch_semaphore_signal(semaphore):將信號量+1

dispatch_once

用于單例處理,相關代碼只會執(zhí)行一次(即使在多核情況下,也是安全的)

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內(nèi)容