前言:
? ?在iOS開發(fā)過程中會遇到多線程和GCD的問題衬横。開發(fā)過程中刨秆,使用多線程是為了提高性能敲董,創(chuàng)造更好的用戶體驗童擎。面試過程中也會經(jīng)常被問到什么是進程,什么是線程歌懒,他們之間的區(qū)別凿歼,子線程的開辟呀癣,GCD什么的划鸽∈漭海考拉平時都是那樣用,從來沒有考慮過裸诽,一把梭子嫂用,就是干。所以想分兩篇讓自己多了解一下多線程崭捍。
名詞理解:
? ?進程:進程就是你在iOS系統(tǒng)上面打開的應用,比如你的QQ或者你自己的應用啰脚,每個進程都是獨立的殷蛇,并且每個進程都運行在自己的內(nèi)存里面。
? ?線程:線程是進程的基本執(zhí)行單位橄浓,一個進程所有的任務都是在線程中執(zhí)行的粒梦。App想要運行就必須要有線程(至少要有一條線程,就是我們長說的主線程)
? ?隊列:一種先進先出的數(shù)據(jù)結(jié)構(gòu)荸实,線程的創(chuàng)建和回收都不需要程序員管匀们,都是隊列來處理,所以你不需要管這個准给。沒用
?(差一句隊列和線程的區(qū)別:隊列是管理線程的相當于線程池泄朴,能夠管理線程什么時候執(zhí)行重抖,隊列就分為串行隊列和并行隊列)
? ?串行隊列(線程的串行):一個線程中任務執(zhí)行是串行的,如果線程要處理多個任務祖灰,那么這些任務就是按照順序進行執(zhí)行的钟沛,1--》2--》3 ?
? ?并行隊列 (線程的并行):一個線程里面的任務執(zhí)行是并行的,如果線程處理多個任務局扶,那么這個任務是同時執(zhí)行的恨统,并不存在先后順序
? ?同步:就是你執(zhí)行完這句代碼的時候,到第二行代碼的時候三妈,上一句代碼肯定是執(zhí)行完了畜埋,這個就是同步。
? ?異步:就是允許在執(zhí)行某一個任務時畴蒲,函數(shù)立刻返回悠鞍,但是真正要執(zhí)行的任務稍后完成。
使用場景:
? ? 一個iOS程序運行后饿凛,默認會開啟一條線程狞玛,成為主線程,或UI線程涧窒。他的作用就是顯示和刷新UI的界面心肪。處理UI的事件(例點擊事件、滾動事件纠吴、拖拽事件等)硬鞍。
注意千萬不要在主線程干的事:
不要將比較耗時的操作放到主線程中(例:下載1G的視頻,這個時候卡主界面)戴已;
耗時操作會卡住主線程固该,嚴重影響UI的流暢度,給用戶一種“卡”的壞體驗糖儡;
多線程:
一個進程可以開啟多條線程伐坏,每條線程可以并行執(zhí)行不同的任務,多線程技術(shù)可以提高程序的執(zhí)行效率握联;
并行執(zhí)行:是指可以同時執(zhí)行桦沉,比如任務A和任務B,在執(zhí)行的時候A和B同時執(zhí)行金闽;
原理:
同一時間纯露,CPU只能處理一條線程,只有一條線程在工作(執(zhí)行)代芜;
多線程并發(fā)執(zhí)行埠褪,其實是CPU快速地在多條線程之間調(diào)度(切換);
如果CUP調(diào)度線程的時間足夠快,就造成了多線程并發(fā)執(zhí)行的假象钞速;
如果CPU開辟N條線程贷掖,會怎樣呢?
CPU會在N多線程之間調(diào)度玉工,CPU會累死羽资,消耗大量的CPU資源,建議最多5條遵班;
每條線程被跳讀執(zhí)行的頻次會減低屠升,反而降低了執(zhí)行效率;
多線程的優(yōu)點:
能適當提高程序的執(zhí)行效率狭郑;
能適當提高資源利用率(CPU腹暖,內(nèi)存利用率);
多線程的缺點:
開啟線程需要占用一定的內(nèi)存空間(默認情況下翰萨,主線程占用1M脏答,子線程占用512KB),如果開啟大量的線程亩鬼,會占用大量的內(nèi)存空間殖告,降低程序的性能 ;
線程越多雳锋,CPU在調(diào)度想成上的開銷就越大黄绩;
程序設計更加復雜:比如線程之間的通信、多線程的數(shù)據(jù)共享玷过;
理解:
其實爽丹,如果不考慮其他任何因素和技術(shù),多線程有百害而無一利辛蚊,只能浪費時間粤蝎,降低程序效率。
(前提是不考慮任何技術(shù)層面和邏輯層面的東西袋马,所以很多人一把梭子上去干初澎,沒有遇到問題,GCD上去就用虑凛,線程亂的一批碑宴,屎一樣的代碼。維護起來難度極大卧檐。但是視頻墓懂,下載焰宣,直播等不用多線程霉囚,就躺著等死就好)
試想一下,一個任務由十個子任務組成∝盎現(xiàn)在有兩種方式完成這個任務: 1. 建十個線程盈罐,把每個子任務放在對應的線程中執(zhí)行榜跌。執(zhí)行完一個線程中的任務就切換到另一個線程。
2. 把十個任務放在一個線程里盅粪,按順序執(zhí)行钓葫。
操作系統(tǒng)的基礎知識告訴我們,線程票顾,是執(zhí)行程序最基本的單元础浮,它有自己棧和寄存器。說得再具體一些奠骄,線程就是“一個CPU執(zhí)行的一條無分叉的命令列”豆同。
對于第一種方法,在十個線程之間來回切換含鳞,就意味著有十組棧和寄存器中的值需要不斷地被備份影锈、替換。 而對于對于第二種方法蝉绷,只有一組寄存器和棧存在鸭廷,顯然效率完勝前者。
后續(xù):
? ? 名詞理解完熔吗,初步完成了辆床。然后萬里長征走了第一步。有用嗎磁滚?沒用佛吓,一點用都沒有。你和我還是啥都不會垂攘。下一篇會寫多線程的實戰(zhàn)部分维雇,從NSThread ,NSOperation&NSOperationQueue 和 GCD 三個對比來理解創(chuàng)建任務晒他,線程吱型,并且進行串行和并且的分析,以及子線程 和主線程和線程鎖代碼的實現(xiàn)陨仅。以及多線程分出來的知識 例如線程同步津滞、延時執(zhí)行、單例模式等等來分析 和代碼的實現(xiàn)灼伤。
? ? 然后一個子線程訪問加鎖的屬性触徐,然后主線程再去訪問,由于加鎖了主線程就在那等著狐赡。撞鹉。。然后影響了體驗。問鸟雏,如何解決享郊。別說分個子線程去訪問,在回到主線程孝鹊,2B的考拉非要主線程去訪問炊琉,怎么優(yōu)化處理。