進(jìn)程
- 進(jìn)程是指系統(tǒng)中正在運行的一個應(yīng)用程序
- 每個進(jìn)程之間是獨立的押框,每個進(jìn)程均運行在其專用且受保護的內(nèi)存空間內(nèi)
線程
- 1個進(jìn)程想要執(zhí)行任務(wù)圈纺,必須有線程(每一個進(jìn)程至少要有1條線程)
- 一個進(jìn)程的所有任務(wù)都是在線程中執(zhí)行
線程的串行
1個線程中任務(wù)的執(zhí)行時串行的
- 如果要在1個線程中執(zhí)行多個任務(wù)兰伤,那么只能一個一個地按順序執(zhí)行這些任務(wù)
- 在同一時間內(nèi),1個線程只能執(zhí)行1個任務(wù)
多線程
什么是多線程
- 1個進(jìn)程中可以開啟多條線程捻激,每條線程可以并行(同時)執(zhí)行不同的任務(wù)
- 進(jìn)程 -> 工廠制轰,線程 -> 工人
- 多線程技術(shù)可以提高程序的執(zhí)行效率
多線程的原理
- 同一時間,CPU只能處理1條線程胞谭,只有1條線程在工作(執(zhí)行)
- 多線程并發(fā)(同時)執(zhí)行垃杖,其實是CPU快速地在多條線程之間調(diào)度(切換)
- 如果CPU調(diào)度線程的時間足夠快,就造成了多線程并發(fā)執(zhí)行的假象
線程開啟非常非常多丈屹,會發(fā)生什么情況调俘?
1伶棒、CPU會在N多線程之間調(diào)度,CPU會累死彩库,消耗大量的CPU資源
2肤无、每條線程被調(diào)度執(zhí)行的頻次會降低(線程的執(zhí)行效率降低)
多線程的優(yōu)缺點
- 優(yōu)點
- 能適當(dāng)提高程序的執(zhí)行效率
- 能適當(dāng)提高資源利用率(CPU、內(nèi)存利用率)
- 缺點
- 創(chuàng)建線程是有開銷的骇钦,創(chuàng)建線程大約需要90毫秒的創(chuàng)建時間
- 如果開啟大量的線程宛渐,會降低程序的性能
- 程序設(shè)計更加復(fù)雜:比如線程之間的通信、多線程的數(shù)據(jù)共享
多線程在iOS開發(fā)中的應(yīng)用
什么是主線程
- 一個iOS程序運行后眯搭,默認(rèn)會開啟1條線程窥翩,稱為“主線程”或“UI線程”
主線程的主要作用
- 顯示、刷新UI界面
- 處理UI事件(點擊事件鳞仙、滾動事件寇蚊、拖拽事件等)
主線程的使用注意
- 別將比較耗時的操作放到主線程中
- 耗時操作會卡住主線程,嚴(yán)重影響UI的流暢度繁扎,給用戶一種“卡”的壞體驗
iOS多線程實現(xiàn)方案
iOS多線程實現(xiàn)方案
多線程的安全隱患
資源共享
- 1塊資源可能會被多個線程共享幔荒,也就是多個線程可能會訪問同一塊資源
- 當(dāng)多個線程訪問同一塊資源時,很容易引發(fā)數(shù)據(jù)錯亂和數(shù)據(jù)安全問題
原子和非原子屬性
OC在定義屬性時有nonatomic和atomic兩種選擇
- atomic:原子屬性梳玫,為setter方法加鎖(默認(rèn)就是atomic)
- nonatomic:非原子屬性,不會為setter方法加鎖
nonatomic和atomic對比
- atomic:線程安全右犹,需要消耗大量的資源
- nonatomic:非線程安全提澎,適合內(nèi)存小的移動設(shè)備
iOS開發(fā)建議
- 所有屬性都聲明為nonatomic
- 盡量避免多線程搶奪同一塊資源
- 盡量將加鎖、資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器端處理念链,減小移動客戶端的壓力
線程間通信
什么叫做線程間通信
- 在1個進(jìn)程中盼忌,線程往往不是孤立存在的,多個線程之間需要經(jīng)常進(jìn)行通信
線程間通信的體現(xiàn)
- 1個線程傳遞數(shù)據(jù)給另1個線程
- 在1個線程中執(zhí)行完特定任務(wù)后掂墓,轉(zhuǎn)到另1個線程繼續(xù)執(zhí)行任務(wù)
GCD
全稱是Grand Central Dispatch谦纱,牛逼的中樞調(diào)度器
- 純C語言,提供了非常多強大的函數(shù)
GCD的優(yōu)勢
- GCD是蘋果公司為多核的并行運算提出的解決方案
- GCD會自動利用更多的CPU內(nèi)核(比如雙核君编、四核)
- GCD會自動管理線程的生命周期(創(chuàng)建線程跨嘉、調(diào)度任務(wù)、銷毀線程)
- 程序員只需要告訴GCD想要執(zhí)行什么任務(wù)吃嘿,不需要編寫任何線程管理代碼
任務(wù)和隊列
GCD中有2個核心概念
- 任務(wù):執(zhí)行什么操作
- 隊列:用來存放任務(wù)
GCD的使用就2個步驟
-
定制任務(wù)
- 確定想做的事情
- 將任務(wù)添加到隊列中
- GCD會自動將隊列中的任務(wù)取出祠乃,放到對應(yīng)的線程中執(zhí)行
- 任務(wù)的取出遵循隊列的FIFO原則:先進(jìn)先出,后進(jìn)后出
執(zhí)行任務(wù)
- GCD中有2個用來執(zhí)行任務(wù)的常用函數(shù)
// 用同步的方式執(zhí)行任務(wù)
// queue:隊列
// block:任務(wù)
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
// 用異步的方式執(zhí)行任務(wù)
// queue:隊列
// block:任務(wù)
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
- 同步和異步的區(qū)別
- 同步:只能在當(dāng)前線程中執(zhí)行任務(wù)兑燥,不具備開啟新線程的能力
- 異步:可以在新的線程中執(zhí)行任務(wù)亮瓷,具備開啟新線程的能力
隊列的類型
GCD的隊列可以分為2大類型
-
并發(fā)隊列(Concurrent Dispatch Queue)
- 可以讓多個任務(wù)并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù))
- 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
-
串行隊列(Serial Dispatch Queue)
- 讓任務(wù)一個接著一個地執(zhí)行(一個任務(wù)執(zhí)行完畢后,在執(zhí)行下一個任務(wù))
容易混淆的術(shù)語
有4個術(shù)語比較容易混淆:同步降瞳、異步嘱支、并發(fā)、串行
-
同步和異步主要影響:能不能開啟新的線程
- 同步:只是在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力
- 異步:可以在新的線程中執(zhí)行任務(wù)除师,具備開啟新線程的能力
-
并發(fā)和串行主要影響:任務(wù)的執(zhí)行方式
- 并發(fā):允許多個任務(wù)并發(fā)(同時)執(zhí)行
- 串行:一個任務(wù)執(zhí)行完畢后沛膳,在執(zhí)行下一個任務(wù)