關(guān)于iOS多線程編程

1基本概念

線程(線程)用于指代獨(dú)立執(zhí)行的代碼段瞒渠。

進(jìn)程(process)用于指代一個(gè)正在運(yùn)行的可執(zhí)行程序,它可以包含多個(gè)線程。?

?任務(wù)(task)用于指代抽象的概念,表示需要執(zhí)行工作舟扎。

多線程讓應(yīng)用程序內(nèi)擁有多個(gè)可執(zhí)行路徑,會(huì)給你的代碼增加更多的復(fù)雜性。每個(gè) 線程需要和其他線程協(xié)調(diào)其行為,以防止它破壞應(yīng)用程序的狀態(tài)信息悴务。因?yàn)閼?yīng)用程序 內(nèi)的多個(gè)線程共享內(nèi)存空間,它們?cè)L問(wèn)相同的數(shù)據(jù)結(jié)構(gòu)睹限。如果兩個(gè)線程試圖同時(shí)處理 相同的數(shù)據(jù)結(jié)構(gòu),一個(gè)線程有可能覆蓋另外線程的改動(dòng)導(dǎo)致破壞該數(shù)據(jù)結(jié)構(gòu)。即使有 適當(dāng)?shù)谋Wo(hù),你仍然要注意由于編譯器的優(yōu)化導(dǎo)致給你代碼產(chǎn)生的微妙影響讯檐。

線程啟動(dòng)之后,線 程就進(jìn)入三個(gè)狀態(tài)中的任何一個(gè):運(yùn)行(running)羡疗、就緒(ready)、阻塞(blocked)别洪。如 果一個(gè)線程當(dāng)前沒(méi)有運(yùn)行,那么它不是處于阻塞,就是等待外部輸入,或者已經(jīng)準(zhǔn)備 就緒等待分配 CPU叨恨。線程持續(xù)在這三個(gè)狀態(tài)之間切換,直到它最終退出或者進(jìn)入中斷 狀態(tài)。

當(dāng)你顯式的中斷線程的時(shí)候,線程永久停止,且被系統(tǒng)回收蕉拢。因?yàn)榫€程創(chuàng)建需 要的內(nèi)存和時(shí)間消耗都比較大,因此建議你的入口點(diǎn)函數(shù)做相當(dāng)數(shù)量的工作,或建立 一個(gè)運(yùn)行循環(huán)允許進(jìn)行經(jīng)常性的工作特碳。

Run Loops (運(yùn)行 循環(huán) )

為了配置 run loop,你所需要做的是啟動(dòng)你的線程,獲取 run loop 的對(duì)象引用, 設(shè)置你的事件處理程序,并告訴 run loop 運(yùn)行诚亚。Cocoa 和 Carbon 提供的基礎(chǔ)設(shè)施會(huì) 自動(dòng)為你的主線程配置相應(yīng)的 run loop。如果你打算創(chuàng)建長(zhǎng)時(shí)間運(yùn)行的輔助線程, 那么你必須為你的線程配置相應(yīng)的 run loop午乓。

同步工具

線程編程的危害之一是在多個(gè)線程之間的資源爭(zhēng)奪站宗。如果多個(gè)線程在同一個(gè)時(shí)間 試圖使用或者修改同一個(gè)資源,就會(huì)出現(xiàn)問(wèn)題。緩解該問(wèn)題的方法之一是消除共享資 源,并確保每個(gè)線程都有在它操作的資源上面的獨(dú)特設(shè)置益愈。因?yàn)楸3滞耆?dú)立的資源 是不可行的,所以你可能必須使用鎖,條件,原子操作和其他技術(shù)來(lái)同步資源的訪問(wèn)


鎖提供了一次只有一個(gè)線程可以執(zhí)行代碼的有效保護(hù)形式梢灭。最普遍的一種鎖是互 斥排他鎖,也就是我們通常所說(shuō)的“mutex”。

除了鎖,系統(tǒng)還提供了條件,確保在你的應(yīng)用程序任務(wù)執(zhí)行的適當(dāng)順序蒸其。一個(gè)條 件作為一個(gè)看門人,阻塞給定的線程,直到它代表的條件變?yōu)檎婷羰汀.?dāng)發(fā)生這種情況的 時(shí)候,條件釋放該線程并允許它繼續(xù)執(zhí)行

盡管鎖和條件在并發(fā)設(shè)計(jì)中使用非常普遍,原子操作也是另外一種保護(hù)和同步訪 問(wèn)數(shù)據(jù)的方法。原子操作在以下情況的時(shí)候提供了替代鎖的輕量級(jí)的方法,其中你可 以執(zhí)行標(biāo)量數(shù)據(jù)類型的數(shù)學(xué)或邏輯運(yùn)算

線程間通信

雖然一個(gè)良好的設(shè)計(jì)最大限度地減少所需的通信量,但在某些時(shí)候,線程之間的 通信顯得十分必要摸袁。

線程可能需要處理新的工作要求,或向你應(yīng)用程 序的主線程報(bào)告其進(jìn)度情況钥顽。在這些情況下,你需要一個(gè)方式來(lái)從其他線程獲取信息。 幸運(yùn)的是,線程共享相同的進(jìn)程空間,意味著你可以有大量的可選項(xiàng)來(lái)進(jìn)行通信靠汁,“配置線程局部存儲(chǔ)”蜂大。

2設(shè)計(jì)技巧

避免顯式創(chuàng)建線程

比如 GCD 和操作對(duì)象技術(shù)被設(shè)計(jì)用來(lái)管 理線程,比通過(guò)自己的代碼根據(jù)當(dāng)前的負(fù)載調(diào)整活動(dòng)線程的數(shù)量更高效

避免共享數(shù)據(jù)結(jié)構(gòu)

避免造成線程相關(guān)資源沖突的最簡(jiǎn)單最容易的辦法是給你應(yīng)用程序的每個(gè)線程一份它需求的數(shù)據(jù)的副本。

主線程刷新你的UI界面

主線程里面接收和界面相關(guān)的事件和初始化更新你的界面

3線程管理(考慮線程成本)

創(chuàng)建一個(gè)線程

使用NSThread

設(shè)置線程的優(yōu)先級(jí)

4Run Loops

5線程同步

同步工具:1原子操作 2鎖 3條件

線程安全設(shè)計(jì)的技巧:

1完全避免同步:實(shí)現(xiàn)并發(fā)最好的方法是減少你并發(fā)任務(wù)之間的交互和相互依賴蝶怔。如果每個(gè)任務(wù)在它自己的數(shù)據(jù)集上面操作,那它不需要使用鎖來(lái)保護(hù)這些數(shù)據(jù)奶浦。甚至如果兩個(gè)任務(wù)共享一個(gè)普通數(shù)據(jù)集,你可以查看分區(qū)方法,它們?cè)O(shè)置或提供拷貝每一項(xiàng)任務(wù)的方法。當(dāng)然,拷貝數(shù)據(jù)集本身也需要成本,所以在你做出決定前,你需要權(quán)衡這些成本和使用同步工具造成的成本那個(gè)更可以接受踢星。

當(dāng)心死鎖(Deadlocks)和活鎖(Livelocks):

任何時(shí)候線程試圖同時(shí)獲得多于一個(gè)鎖,都有可能引發(fā)潛在的死鎖澳叉。當(dāng)兩個(gè)不同的線程分別保持一個(gè)鎖(而該鎖是另外一個(gè)線程需要的)又試圖獲得另外線程保持的鎖時(shí)就會(huì)發(fā)生死鎖。結(jié)果是每個(gè)線程都會(huì)進(jìn)入持久性阻塞狀態(tài),因?yàn)樗肋h(yuǎn)不可能獲得另外那個(gè)鎖沐悦。

一個(gè)活鎖和死鎖類似,當(dāng)兩個(gè)線程競(jìng)爭(zhēng)同一個(gè)資源的時(shí)候就可能發(fā)生活鎖成洗。在發(fā)生活鎖的情況里,一個(gè)線程放棄它的第一個(gè)鎖并試圖獲得第二個(gè)鎖。一旦它獲得第二個(gè)鎖,它返回并試圖再次獲得一個(gè)鎖所踊。線程就會(huì)被鎖起來(lái),因?yàn)樗ㄙM(fèi)所有的時(shí)間來(lái)釋放一個(gè)鎖,并試圖獲取其他鎖,而不做實(shí)際的工作泌枪。

避免死鎖和活鎖的最好方法是同一個(gè)時(shí)間只擁有一個(gè)鎖。如果你必須在同一時(shí)間獲取多于一個(gè)鎖,你應(yīng)該確保其他線程沒(méi)有做類似的事情秕岛。

使用原子操作:

獲取一個(gè)鎖是一個(gè)很昂貴的操作,即使在無(wú)競(jìng)爭(zhēng)的狀態(tài)下碌燕。相比,許多原子操作花費(fèi)很少的時(shí)間來(lái)完成操作也可以達(dá)到和鎖一樣的效果。

使用鎖:

1使用POSIX互斥鎖:為了新建一個(gè)互斥鎖,你聲明并初始化一個(gè)pthread_mutex_t的結(jié)構(gòu)继薛。為了鎖住和解鎖一個(gè)互斥鎖,你可以使用pthread_mutex_lock和pthread_mutex_unlock函數(shù)修壕。

2使用NSLock類:

3使用@synchronized指令

4使用NSRecursiveLock對(duì)象

5使用NSConditionLock對(duì)象

6使用NSDistributedLock對(duì)象

使用條件

1使用NSCondition類

2使用POSIX條件

本文章純理論,對(duì)多線程的基本概念的理解遏考,摘自多線程編程指南慈鸠,原著:Apple Inc.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灌具,隨后出現(xiàn)的幾起案子青团,更是在濱河造成了極大的恐慌譬巫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件督笆,死亡現(xiàn)場(chǎng)離奇詭異芦昔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)娃肿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門咕缎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人料扰,你說(shuō)我怎么就攤上這事凭豪。” “怎么了晒杈?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵嫂伞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拯钻,道長(zhǎng)末早,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任说庭,我火速辦了婚禮,結(jié)果婚禮上郑趁,老公的妹妹穿的比我還像新娘刊驴。我一直安慰自己,他們只是感情好寡润,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布捆憎。 她就那樣靜靜地躺著,像睡著了一般梭纹。 火紅的嫁衣襯著肌膚如雪躲惰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天变抽,我揣著相機(jī)與錄音础拨,去河邊找鬼。 笑死绍载,一個(gè)胖子當(dāng)著我的面吹牛诡宗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播击儡,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼塔沃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了阳谍?” 一聲冷哼從身側(cè)響起蛀柴,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤螃概,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鸽疾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吊洼,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年肮韧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了融蹂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡弄企,死狀恐怖超燃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拘领,我是刑警寧澤意乓,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站约素,受9級(jí)特大地震影響届良,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜圣猎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一士葫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧送悔,春花似錦慢显、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至洁段,卻和暖如春应狱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祠丝。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工疾呻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纽疟。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓罐韩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親污朽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子散吵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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

  • 引用自多線程編程指南應(yīng)用程序里面多個(gè)線程的存在引發(fā)了多個(gè)執(zhí)行線程安全訪問(wèn)資源的潛在問(wèn)題。兩個(gè)線程同時(shí)修改同一資源有...
    Mitchell閱讀 1,992評(píng)論 1 7
  • 本文將從以下幾個(gè)部分來(lái)介紹多線程。 第一部分介紹多線程的基本原理矾睦。 第二部分介紹Run loop晦款。 第三部分介紹多...
    曲年閱讀 1,266評(píng)論 2 14
  • 由于文章長(zhǎng)度限制,本文作為[譯]線程編程指南(一)后續(xù)部分枚冗。 Run Loops Run loop是與線程相關(guān)的基...
    巧巧的二表哥閱讀 1,185評(píng)論 0 5
  • 本文選譯自《Threading Programming Guide》缓溅。 導(dǎo)語(yǔ) 線程技術(shù)作為在單個(gè)應(yīng)用程序中并發(fā)執(zhí)行...
    巧巧的二表哥閱讀 2,437評(píng)論 4 24
  • 由于文章長(zhǎng)度限制,本文作為[譯]線程編程指南(二)后續(xù)部分赁温。 線程安全技巧 同步工具是保證代碼線程安全的有效方式坛怪,...
    巧巧的二表哥閱讀 1,325評(píng)論 0 4