iOS多線程

首先每個(gè)正在運(yùn)行的應(yīng)用程序都是一個(gè)進(jìn)程恭应,每個(gè)進(jìn)程系統(tǒng)都會分配獨(dú)立的內(nèi)存資源抄邀。而一個(gè)進(jìn)程中的所有任務(wù)都是在線程中執(zhí)行的,所以每個(gè)進(jìn)程至少有一個(gè)線程昼榛,這個(gè)線程也稱為主線程境肾,而如果想要并發(fā)執(zhí)行多個(gè)任務(wù)那么就要開啟多條線程剔难,也稱為多線程。多線程在一定意義上實(shí)現(xiàn)了進(jìn)程內(nèi)的資源共享奥喻,以及效率的提升偶宫。同時(shí),在一定程度上相對獨(dú)立环鲤,是執(zhí)行任務(wù)最基本的單元纯趋,有自己棧和寄存器。而對應(yīng)單核 CPU 來說冷离,多線程并不是真正意義上并發(fā)執(zhí)行任務(wù)吵冒,只是CPU快速地在多條線程之間調(diào)度,CPU調(diào)度線程的時(shí)間足夠短西剥,就造成了多線程并發(fā)執(zhí)行的假象痹栖。就單核CPU而言多線程可以解決線程阻塞的問題,但是其本身效率并沒有提高瞭空,多核CPU的并行才真正解決了運(yùn)行效率問題揪阿。

上面這段抄的,來源在這


iOS 多線程方案

1. pthread 這個(gè)是一套 C 語言跨平臺多線程 API咆畏,其產(chǎn)生的線程生命周期是需要手動(dòng)管理

2. NSThread 是蘋果對 pthread 面向?qū)ο蟮姆庋b南捂,和上面一樣是需要手動(dòng)管理線程生命周期

3. GCD 是蘋果另一套多線程解決方案,其線程生命周期是自動(dòng)管理鳖眼,使用簡單黑毅,也是最常使用的

4. NSOperation 是蘋果基于 GCD 面向?qū)ο蠓庋b,提供了一實(shí)用的功能钦讳,例如設(shè)置線程最大并發(fā)數(shù)矿瘦,添加線程間依賴等


GCD

首先在 GCD 中并不直接操作線程,而是通過其提供的任務(wù)管理方式隊(duì)列和任務(wù)執(zhí)行方式同步和異步愿卒,間接管理線程

隊(duì)列作用:任務(wù)的執(zhí)行方式

隊(duì)列分為兩種缚去,一種是是串行隊(duì)列,一種是并發(fā)隊(duì)列

串行隊(duì)列:一個(gè)任務(wù)完成后再執(zhí)行下一個(gè)任務(wù)琼开,根據(jù)先進(jìn)先出的按順序執(zhí)行

并發(fā)隊(duì)列:多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行

特殊的隊(duì)列:全局隊(duì)列和主隊(duì)列

全局隊(duì)列是并發(fā)隊(duì)列易结,而主隊(duì)列是在主線程上,是串行隊(duì)列

同步和異步作用:能不能開啟新的線程

同步:在當(dāng)前線程中執(zhí)行任務(wù)柜候,不具備開啟新線程的能力

異步:在新的線程中執(zhí)行任務(wù)搞动,具備開啟新線程的能力

只要是同步或主隊(duì)列兩者占一項(xiàng),就不會開啟新線程渣刷,串行執(zhí)行任務(wù)鹦肿;

只有異步并且不是主隊(duì)列,才會開啟新線程辅柴,根據(jù)其搭配的隊(duì)列并發(fā)或串行是否執(zhí)行任務(wù)

在 GCD 中使用 sync 同步函數(shù)往當(dāng)前串行隊(duì)列添加任務(wù)箩溃,就會產(chǎn)生死鎖阻塞線程


常用函數(shù)?

dispatch_sync 同步執(zhí)行任務(wù)

dispatch_async 異步執(zhí)行任務(wù)

dispatch_once 只執(zhí)行一次使當(dāng)前添加的任務(wù)瞭吃,并且是線程安全的,常用于創(chuàng)建單例對象

dispatch_apply 使當(dāng)前添加的任務(wù)執(zhí)行指定次數(shù)涣旨,這個(gè)相當(dāng)于內(nèi)置循環(huán)執(zhí)行多次任務(wù)歪架,這個(gè)函數(shù)會調(diào)用主線程執(zhí)行任務(wù),如果是任務(wù)耗時(shí)不要使用霹陡,使用手動(dòng)設(shè)置循環(huán)調(diào)用多次異步并發(fā)隊(duì)列執(zhí)行耗時(shí)任務(wù)

dispatch_after 使任務(wù)延遲執(zhí)行

dispatch_group_async 與?dispatch_group_notify 添加任務(wù)依賴和蚪,執(zhí)行完前者的任務(wù)之后都會執(zhí)行后者的任務(wù)

dispatch_group_wait 會阻塞當(dāng)前線程,等待 group 中的任務(wù)執(zhí)行完烹棉,之后再回到當(dāng)前線程執(zhí)行

dispatch_barrier_async 并發(fā)執(zhí)行任務(wù)時(shí)惠呼,當(dāng)前添加任務(wù)不會執(zhí)行,執(zhí)行當(dāng)前任務(wù)時(shí)是串行執(zhí)行峦耘,使用場景 IO的多讀單寫


線程同步方案

OSSpinLock

這個(gè)是自旋鎖,等待鎖的線程會處于忙等狀態(tài)旅薄,一直占用 CPU 資源辅髓,從 iOS10開始,會出現(xiàn)警告少梁,因?yàn)檫@個(gè)鎖不再安全洛口,可能會出現(xiàn)優(yōu)先級反轉(zhuǎn)的問題,如果等待的線程優(yōu)先級較高凯沪,它會一直占用?CPU 資源第焰,優(yōu)先級低的線程就無法釋放鎖資源

os_unfair_lock

是 iOS10之后才支持的,是 apple 用來取代 OSSpinLock 一種線程同步方案妨马,是互斥鎖挺举,和自旋鎖區(qū)別在于等待鎖資源的線程會處于休眠狀態(tài),并非忙等狀態(tài)

一般開啟多線程時(shí)烘跺,如果涉及到線程同步的說湘纵,不建議修改線程優(yōu)先級,容易出現(xiàn)優(yōu)先級反轉(zhuǎn)的問題滤淳,特別是使用 OSSpinLock 時(shí)

一般來說梧喷,只要不是對耗時(shí)任務(wù)進(jìn)行使用線程同步,那么使用自旋鎖的效率和開銷會優(yōu)于互斥鎖脖咐,因?yàn)榫€程執(zhí)行任務(wù)的時(shí)間短铺敌,自旋鎖會一直忙等,及時(shí)拿到鎖資源屁擅,如果是互斥鎖偿凭,因?yàn)榫€程執(zhí)行任務(wù)的時(shí)間短,這種頻繁休眠喚醒操作會增加資源開銷煤蹭,降低效率笔喉,如果是耗時(shí)任務(wù)線程同步取视,那么使用互斥鎖優(yōu)于自旋鎖,因?yàn)樽孕i等待的線程處于激活狀態(tài)一直訪問鎖資源常挚,而另外拿到鎖資源的線程此時(shí)還沒給 CPU 調(diào)度到作谭,所以此時(shí)耗時(shí)任務(wù)沒有執(zhí)行完,無法釋放鎖資源奄毡,此時(shí)會降低效率

兩者 api 幾乎一樣折欠,鎖的初始化都是宏定義提供的,前者宏定義是0吼过,后者是將 os_unfair_lock 結(jié)構(gòu)體初始化

#define OS_SPINLOCK_INIT? ? 0

#define OS_UNFAIR_LOCK_INIT ((os_unfair_lock){0})

提供的3個(gè)函數(shù) lock unlock tryLock

tryLock 表示锐秦,當(dāng)前是否能拿到鎖資源,能就返回 YES盗忱,可以配合 if 一起使用

pthread_mutex

mutex 表示互斥鎖酱床,是一套 c 語言的跨平臺線程同步 api

初始化是,可以選擇鎖的類型趟佃,一種是默認(rèn)就是互斥鎖扇谣,一種是遞歸鎖

遞歸鎖的特性是,不同線程間就跟互斥鎖特性一樣闲昭,但是可以讓同一個(gè)線程多次獲取鎖資源罐寨,主要使用場景就是對一個(gè)遞歸方法進(jìn)行線程同步

mutex 這套 api 還有個(gè)特點(diǎn)就是給線程添加條件 condition

他提供了三個(gè)函數(shù)

pthread_cond_wait() 接收兩個(gè)參數(shù),一個(gè)是條件序矩,一個(gè)線程鸯绿,可以讓當(dāng)前線程等待,因?yàn)槭腔コ怄i 簸淀,等待時(shí)會休眠瓶蝴,同時(shí)釋放鎖的資源,等待被當(dāng)前條件重新激活租幕,激活時(shí)會喚醒囊蓝,線程重新拿到鎖的資源

pthread_cond_signal() 會激活一個(gè)等待該條件的線程

pthread_cond_broadcast() 激活所有等待該條件的線程

NSLock

是 apple 對?mutex 互斥鎖的面向?qū)ο蠓庋b?

NSRecursiveLock

是 apple 對 mutex?遞歸鎖的面向?qū)ο蠓庋b?

NSCondition

是 apple 對?mutex 條件的面向?qū)ο蠓庋b?

NSConditionLock

這個(gè) NSCondition 進(jìn)一步的封裝,這點(diǎn)在于可以設(shè)置具體的條件值令蛉,只有滿足條件值的線程才能拿到鎖的資源聚霜,在釋放鎖的資源時(shí)可以更改條件值

@synchronized

也是對 mutex 遞歸鎖封裝,@synchronized(obj) 其內(nèi)部會生成 obj 對應(yīng)的遞歸鎖珠叔,然后進(jìn)行加鎖蝎宇、解鎖操作,但是性能不好祷安,不推薦使用


GCD 提供線程同步方案

dispatch_semaphore

semaphore 也就是信號量姥芥,這個(gè)信息量可以用來控制線程并發(fā)訪問量大數(shù)量

當(dāng)設(shè)置信號量為1,代表同時(shí)只允許1條線程訪問資源汇鞭,保證線程同步

提供 3個(gè)函數(shù)

dispatch_semaphore_create(value) 初始化信息號

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 如果信息量的值 <=0凉唐,當(dāng)前線程就會進(jìn)入休眠等待庸追,直到信息量的值 >0,如果信息量的值 >0 就減 1台囱,讓線程往下執(zhí)行后面的代碼

dispatch_semaphore_signal(semaphore) 讓信息號加1

wait 和 signal 和之前 condition 條件很像

DISPATCH_QUEUE_SERIAL

直接使用 GCD 的串行隊(duì)列淡溯,也是可以實(shí)現(xiàn)線程同步的


讀寫安全方案-多讀單寫

pthread_rwlock 讀寫鎖

dispatch_barrier_async 異步柵欄函數(shù)?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市簿训,隨后出現(xiàn)的幾起案子咱娶,更是在濱河造成了極大的恐慌,老刑警劉巖强品,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膘侮,死亡現(xiàn)場離奇詭異,居然都是意外死亡的榛,警方通過查閱死者的電腦和手機(jī)琼了,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夫晌,“玉大人表伦,你說我怎么就攤上這事】独觯” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵鳄哭,是天一觀的道長要糊。 經(jīng)常有香客問我,道長妆丘,這世上最難降的妖魔是什么锄俄? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮勺拣,結(jié)果婚禮上奶赠,老公的妹妹穿的比我還像新娘。我一直安慰自己药有,他們只是感情好毅戈,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著愤惰,像睡著了一般苇经。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宦言,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天扇单,我揣著相機(jī)與錄音,去河邊找鬼奠旺。 笑死蜘澜,一個(gè)胖子當(dāng)著我的面吹牛施流,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鄙信,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼瞪醋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扮碧?” 一聲冷哼從身側(cè)響起趟章,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慎王,沒想到半個(gè)月后蚓土,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赖淤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年蜀漆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咱旱。...
    茶點(diǎn)故事閱讀 38,117評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡确丢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吐限,到底是詐尸還是另有隱情鲜侥,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布诸典,位于F島的核電站描函,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏狐粱。R本人自食惡果不足惜舀寓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肌蜻。 院中可真熱鬧互墓,春花似錦、人聲如沸蒋搜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豆挽。三九已至酸休,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間祷杈,已是汗流浹背斑司。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宿刮。 一個(gè)月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓互站,卻偏偏與公主長得像,于是被迫代替她去往敵國和親僵缺。 傳聞我的和親對象是個(gè)殘疾皇子胡桃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評論 2 345

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

  • iOS多線程編程 基本知識 1. 進(jìn)程(process) 進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序,就是一段程序的執(zhí)...
    陵無山閱讀 6,005評論 1 14
  • 前言: 最近想回顧一下多線程問題,看到一篇文章寫的非常詳細(xì),為了便于以后查找以及加深印象,就照著原文摘錄了下文,原...
    FM_0138閱讀 938評論 1 1
  • 前言 iOS開發(fā)中由于各種第三方庫的高度封裝磕潮,對鎖的使用很少翠胰,剛好之前面試中被問到的關(guān)于并發(fā)編程鎖的問題,都是一知...
    喵渣渣閱讀 3,685評論 0 33
  • 多線程 在iOS開發(fā)中為提高程序的運(yùn)行效率會將比較耗時(shí)的操作放在子線程中執(zhí)行自脯,iOS系統(tǒng)進(jìn)程默認(rèn)啟動(dòng)一個(gè)主線程之景,用...
    郭豪豪閱讀 2,587評論 0 4
  • 請點(diǎn)擊藍(lán)字收聽朗讀音頻 作者:王寅
    云中飄舞閱讀 687評論 10 27