Apple: 并發(fā)編程總覽

文章結(jié)構(gòu)

摘要:本文參考 Apple 官方文檔 Concurrency Programming Guide臭杰,從總體上介紹并發(fā)編程的相關(guān)內(nèi)容廓啊,涉及 NSOperation 和 GCD旷痕。

前言

并發(fā)(Concurrency)指的是多個事件同時發(fā)生并淋。當(dāng) App 有多個任務(wù)要完成時醋安,把其中一部分放在其他線程(Thread)里能充分利用 CPU 資源刁憋。

對于早期的計算機(jī)滥嘴,單位時間處理的任務(wù)量取決于 CPU 的時鐘頻率。但是隨著技術(shù)的發(fā)展至耻,單核 CPU 的時鐘頻率提升逐漸達(dá)到瓶頸若皱。因此 CPU 開始采用多核心的設(shè)計镊叁,來提高性能。

讓一個 App 使用多核心的傳統(tǒng)方法是創(chuàng)建多個線程走触,但是手動操作和管理線程晦譬,難度很大,并且很難保證性能饺汹,如:線程的數(shù)目要適當(dāng)蛔添,并且隨著系統(tǒng)運(yùn)行的狀態(tài)進(jìn)行調(diào)整。

為此 Apple 提供了以下幾種負(fù)責(zé)處理多核兜辞、多線程的解決方案:

  1. Grand Central Dispatch(GCD)迎瞧;
  2. Operation Queues;
  3. OpenCL 等逸吵。

GCD 與 Operation Queues

首先我們對比一下 GCD 與 Operation Queues凶硅。

GCD 基于 C 語言,它提供了簡潔的并發(fā)編程 API扫皱。

Operation Queues足绅,在 Cocoa 里對應(yīng) NSOperation 和 NSOperationQuque,是 Objective-C 類韩脑。它實(shí)現(xiàn)了類似于 GCD 的功能氢妈。

Operation Queues 最先引入,但是到了 OS 10.6 和 iOS 4段多,NSOperationQueue 的內(nèi)部代碼就使用 GCD 實(shí)現(xiàn)了首量。也就是說,在最新的 OS X 和 iOS 系統(tǒng)里进苍,NSOperation 其實(shí)就是使用了 GCD加缘,但它并不是簡單的調(diào)用 GCD,它還實(shí)現(xiàn)了一些復(fù)雜的方法觉啊。

Dispatch Queues

GCD 包含 Dispatch Queues 和 Dispatch Sources拣宏。

Dispatch Queues 的執(zhí)行方式有兩種:

  1. Concurrent(并發(fā),可以同時開始多個任務(wù))杠人;
  2. Serial(串行勋乾,一個任務(wù)完成后才開始下一個任務(wù))。

它們都是先入先出(FIFO)嗡善,需要把執(zhí)行的代碼放到函數(shù)或 Block 里市俊。

Dispatch Sources

Dispatch Sources 基于 C 語言,用于異步處理特殊類型的系統(tǒng)事件滤奈。當(dāng)事件發(fā)生時摆昧,dispatch source 會封裝一些系統(tǒng)事件的信息,通過函數(shù)或 Block 提交到 dispatch queue 里蜒程。幾種系統(tǒng)事件的類型如下:

  • Timers
  • Signal handlers
  • Descriptor-related events
  • Process-related events
  • Mach port events
  • Custom events that you trigger

Operation Queues

Dispatch Queue 總是以 FIFO 的順序執(zhí)行绅你,而 Operation Queue 可以通過設(shè)置參數(shù)伺帘,實(shí)現(xiàn)對執(zhí)行順序的控制。如:可以設(shè)定當(dāng)一個任務(wù)完成后忌锯,才能執(zhí)行下一個任務(wù)伪嫁;可以構(gòu)建復(fù)雜的執(zhí)行圖(Graph)。

提交給 Operation Queue 的任務(wù)是一個 NSOperation 的實(shí)例偶垮。NSOperation 本身是一個抽象的類张咳,NSInvocationOperation 和 NSBlockOperation 繼承自 NSOperation。因此似舵,我們可以使用 NSInvocationOperation 和 NSBlockOperation 或使用自己創(chuàng)建的 NSOperation 子類來創(chuàng)建任務(wù)脚猾。

還有,由于 NSOperation 繼承自 NSObject砚哗,且其對象會發(fā)出 KVO 消息龙助。所以可以通過 KVO 來檢測 Operation 的執(zhí)行情況。

異步設(shè)計技術(shù)

使用 Concurrency 能充分利用多核心蛛芥,讓主線程關(guān)注于用戶的操作提鸟,而把其他任務(wù)交給另外的線程。但是這會極大增加代碼的復(fù)雜度仅淑,并且加大維護(hù)難度称勋,因此要做出權(quán)衡。

確定要執(zhí)行的任務(wù)

進(jìn)行異步設(shè)計涯竟,首先確定 App 要完成的任務(wù)铣缠,按優(yōu)先級列出,并考慮它們之間的關(guān)系昆禽。

弄清任務(wù)的執(zhí)行步驟

考慮任務(wù)的每一步(Unit),分析是否能通過多線程優(yōu)化蝇庭,以及能得到多大的性能提升醉鳖。在不熟悉 NSThread(更底層的線程操作類) 的情況下,使用 queue 可能會比使用 NSThread 效果更好哮内。

確定 Queue 的類型

把任務(wù)分成各個步驟(Unit)后盗棵,把它們放到 Block 或 Operation Object 里,確定它們的執(zhí)行順序北发。

  1. 若使用 Block纹因,考慮添加到 Serial dispatch queue 或 Concurrency dispatch queue。
  2. 若使用 Operation Objects琳拨,queue 的選擇相比 operation object 的設(shè)置就不那么重要了瞭恰。主要設(shè)置好各個 object 之間的關(guān)系。

小技巧

  1. 考慮直接在進(jìn)行的任務(wù)中求值狱庇,而不用回到主線程獲取數(shù)值惊畏。由于線程的切換會有額外的開銷恶耽,應(yīng)避免頻繁切換線程;
  2. 盡早確定順序執(zhí)行的任務(wù)(serial tasks)颜启;
  3. 避免使用鎖(lock)偷俭;
  4. 盡量使用系統(tǒng)框架。

其它并發(fā)技術(shù)

OpenCL

OpenCL(Open Computing Language)是 OS X 上的一個并發(fā)技術(shù)缰盏,用于使用 GPU 進(jìn)行數(shù)值計算涌萤。如:利用 GPU 對一張圖片中的每個像素點(diǎn)進(jìn)行處理,計算出處理后的數(shù)值口猜。

需要注意的是负溪,使用 OpenCL 是有一定額外開銷的,把數(shù)據(jù)傳入 GPU 和從 GPU 獲取結(jié)果數(shù)據(jù)都需要時間暮的,因此不能濫用 OpenCL笙以。

何時使用線程(Threads)

雖然 Operation Queues 和 Dispatch Queues 在處理并發(fā)任務(wù)上很適用,但是它們并不是萬能的冻辩。根據(jù)實(shí)際的情況猖腕,有時需要手動創(chuàng)建線程,這樣能對線程有更精確的控制恨闪。關(guān)于線程的使用倘感,請參考 Threading Programming Guide

參考:Concurrency Programming Guide咙咽。

有任何疑問的話老玛,歡迎在下方評論區(qū)討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钧敞,一起剝皮案震驚了整個濱河市蜡豹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溉苛,老刑警劉巖镜廉,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愚战,居然都是意外死亡娇唯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門寂玲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塔插,“玉大人,你說我怎么就攤上這事拓哟∠胄恚” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伸刃。 經(jīng)常有香客問我谎砾,道長,這世上最難降的妖魔是什么捧颅? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任景图,我火速辦了婚禮,結(jié)果婚禮上碉哑,老公的妹妹穿的比我還像新娘挚币。我一直安慰自己,他們只是感情好扣典,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布妆毕。 她就那樣靜靜地躺著,像睡著了一般贮尖。 火紅的嫁衣襯著肌膚如雪笛粘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天湿硝,我揣著相機(jī)與錄音薪前,去河邊找鬼。 笑死关斜,一個胖子當(dāng)著我的面吹牛示括,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痢畜,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼垛膝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丁稀?” 一聲冷哼從身側(cè)響起吼拥,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎线衫,沒想到半個月后凿可,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡桶雀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了唬复。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矗积。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖敞咧,靈堂內(nèi)的尸體忽然破棺而出棘捣,到底是詐尸還是另有隱情,我是刑警寧澤休建,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布乍恐,位于F島的核電站评疗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茵烈。R本人自食惡果不足惜百匆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呜投。 院中可真熱鬧加匈,春花似錦、人聲如沸仑荐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粘招。三九已至啥寇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洒扎,已是汗流浹背辑甜。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逊笆,地道東北人栈戳。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像难裆,于是被迫代替她去往敵國和親子檀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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