iOS多線程基本介紹

多線程

1、線程的定義
  • 線程是進(jìn)程的基本執(zhí)行單元,一個進(jìn)程的所有任務(wù)都在線程中執(zhí)行
  • 進(jìn)程要想執(zhí)行任務(wù),必須得有線程,進(jìn)程至少要有一條線程
  • 程序啟動會默認(rèn)開啟一條線程,這條線程被稱為主線程或 UI 線程
2、進(jìn)程的定義
  • 進(jìn)程是指在系統(tǒng)中正在運行的一個應(yīng)用程序
  • 每個進(jìn)程之間是獨立的,每個進(jìn)程均運行在其專用的且受保護的內(nèi)存
3、進(jìn)程與線程的關(guān)系
  • 地址空間:同一進(jìn)程的線程共享本進(jìn)程的地址空間,而進(jìn)程之間則是獨立的地址空間。
  • 資源擁有:同一進(jìn)程內(nèi)的線程共享本進(jìn)程的資源如內(nèi)存、I/O、cpu等,但是進(jìn)程之間的資源是獨立的。
  • 一個進(jìn)程崩潰后,在保護模式下不會對其他進(jìn)程產(chǎn)生影響,但是一個線程崩潰整個進(jìn)程都死掉。所以多進(jìn)程要比多線程健壯。
  • 進(jìn)程切換時,消耗的資源大,效率高。所以涉及到頻繁的切換時,使用線程要好于進(jìn)程。同樣如果要求同時進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程不能用進(jìn)程
  • 執(zhí)行過程:每個獨立的進(jìn)程有一個程序運行的入口、順序執(zhí)行序列和程序入口。但是線程不能獨立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個線程執(zhí)行控制。
  • 線程是處理器調(diào)度的基本單位,但是進(jìn)程不是。
4、多線程的意義
  • 優(yōu)點
    • 能適當(dāng)提高程序的執(zhí)行效率
    • 能適當(dāng)提高資源的利用率(CPU,內(nèi)存)
    • 線程上的任務(wù)執(zhí)行完成后,線程會自動銷毀
  • 缺點
    • 開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下,每一個線程都占 512 KB)
    • 如果開啟大量的線程,會占用大量的內(nèi)存空間,降低程序的性能
    • 線程越多,CPU 在調(diào)用線程上的開銷就越大
    • 程序設(shè)計更加復(fù)雜,比如線程間的通信、多線程的數(shù)據(jù)共享
5、多線程的原理

cpu在單位時間片里快速在各個線程之間切換。實現(xiàn)假象的同時執(zhí)行。


image.png
6、多線程在iOS中實現(xiàn)的技術(shù)方案
image.png
7、多線程的生命周期

多線程在線程池中主要有下圖這幾種狀態(tài):當(dāng)創(chuàng)建后,有任務(wù)就會被CPU調(diào)度,執(zhí)行任務(wù),此時可能阻塞,任務(wù)執(zhí)行完畢就退出。
阻塞之后如果需要會再次添加到線程池中,等待下次調(diào)度。


image.png
8、線程添加到線程池

線程添加到線程池是有原則的,因為線程池的大小是一定的。
主要條件有三個:

  • 核心線程池大小。如果線程池的大小小于核心線程池,那么可以創(chuàng)建線程;
  • 工作隊列。如果工作隊列已經(jīng)未滿,那么添加到隊列,創(chuàng)建線程;
  • 線程是否都工作。如果沒有都工作,那么創(chuàng)建線程。


    image.png
飽和策略

蘋果提供了api可以進(jìn)行設(shè)置

  • 中止
  • 拋棄
  • 退回
  • 等待
  • push

線程和RunLoop的關(guān)系

  1. runloop與線程是一一對應(yīng)的,一個runloop對應(yīng)一個核心的線程,為什么說是核心的,是因為runloop是可以嵌套的,但是核心的只能有一個,他們的關(guān)系保存在一個全局的字典里。
  2. runloop是來管理線程的,當(dāng)線程的runloop被開啟后,線程會在執(zhí)行完任務(wù)后進(jìn)入休眠狀態(tài),有了任務(wù)就會被喚醒去執(zhí)行任務(wù)。
  3. runloop在第一次獲取時被創(chuàng)建,在線程結(jié)束時被銷毀。
  4. 對于主線程來說,runloop在程序一啟動就默認(rèn)創(chuàng)建好了。
  5. 對于子線程來說,runloop是懶加載的,只有當(dāng)我們使用的時候才會創(chuàng)建,所以在子線程用定時器要注意:確保子線程的runloop被創(chuàng)建,不然定時器不會回調(diào)。
    RunLoop和線程在一個字典中呈現(xiàn)一一對應(yīng)的關(guān)系,其中線程的指針為key;RunLoop使得線程存活,也就是常駐;線程退出時使得RunLoop結(jié)束。
C于OC的橋接小知識
  • __bridge只做類型轉(zhuǎn)換,但是不修改對象(內(nèi)存)管理權(quán);
  • __bridge_retained(也可以使用CFBridgingRetain)將Objective-C的對象轉(zhuǎn)換為Core Foundation的對象,同時將對象(內(nèi)存)的管理權(quán)交給我們,后續(xù)需要使用CFRelease或者相關(guān)方法來釋放對象;
  • __bridge_transfer(也可以使用CFBridgingRelease)將Core Foundation的對象轉(zhuǎn)換為Objective-C的對象,同時將對象(內(nèi)存)的管理權(quán)交給ARC。
為什么要在主線程更新UI?

蘋果就是這樣設(shè)計的,這是一套設(shè)計的標(biāo)準(zhǔn)。
蘋果要求在主線程中更新UI操作,操作系統(tǒng)便于執(zhí)行;
為了用戶體驗,一些UI上的交互肯定是給用戶直接交互比較好,多數(shù)情況下,UI是直接展現(xiàn)給用戶的,所以在主線程展示不至于卡頓或者突兀。

如何辦到的手動控制線程生命周期

因為GCD完全是自動控制線程生命周期,只需要將任務(wù)交給他執(zhí)行,執(zhí)行完畢會自動控制銷毀,所以有時候并不能完全滿足我們的要求,比如有時候我們想要取消正在執(zhí)行的任務(wù)時。所以一般可以重寫start等方法來實現(xiàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,675評論 1 32
  • iOS多線程編程 基本知識 1. 進(jìn)程(process) 進(jìn)程是指在系統(tǒng)中正在運行的一個應(yīng)用程序,就是一段程序的執(zhí)...
    陵無山閱讀 6,351評論 1 14
  • 1.內(nèi)存的頁面置換算法 (1)最佳置換算法(OPT)(理想置換算法):從主存中移出永遠(yuǎn)不再需要的頁面;如無這樣的...
    杰倫哎呦哎呦閱讀 3,596評論 1 9
  • ??一個任務(wù)通常就是一個程序,每個運行中的程序就是一個進(jìn)程。當(dāng)一個程序運行時,內(nèi)部可能包含了多個順序執(zhí)行流,每個順...
    OmaiMoon閱讀 1,804評論 0 12
  • 又來到了一個老生常談的問題,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢? 今天就這個問題開始,來談?wù)劜?..
    tangsl閱讀 4,324評論 0 23

友情鏈接更多精彩內(nèi)容