OS X 和iOS 中的多線程技術(上)
本文梳理了OS X 和iOS 系統中提供的多線程技術。並且對這些技術的使用給出了一些實用的建議。
多線程的目的:通過並發執行提高 CPU 的使用效率,進而提供程序運行效率。
1.線程和進程進程什麼是進程
- 進程是指在計算機系統中
正在運行
的一個應用程序 - 每個進程之間是
獨立
的,每個進程均運行中其專用且受保護的內存空間內
- 進程是指在計算機系統中
比如同時打開 Xcode 、Safari ,系統就會分別啟動兩個進程
- 通過
活動監視器
可以查看Mac系統中所開啟的進程
線程
- 什麼是線程
- 一個進程要想執行任務,
必須
得有線程(每個線程至少有一條線程,即主線程
) - 一個進程的所有任務都做線程中執行
- 一個進程要想執行任務,
- 比如使用酷狗播放音樂、使用迅雷下載電影,都需要在線程中執行
- 一個線程中的任務的執行是
串列
的- 如果要在一個線程中執行多個任務,那麼只能一個一個地按順序執行這些任務
- 同一時間內,一個線程只能執行一個任務
- 線程是進程中的一條執行路徑,它內部任務是
串列
執行的
多線程
- 什麼是多線程
- 一個進程中可以開啟多條線程,每條線程可以
並行(同時)
執行不同的任務 - 進程好比車間,線程好比車間工人
- 多線程技術可以提高程序的執行效率
- 一個進程中可以開啟多條線程,每條線程可以
- 如同時開啟3條線程分別下載3個文件
- 多線程的原理
- 同一時間,CPU只能處理1條線程,只有1條線程在工作(執行)
- 多線程並發(同時)執行,其實是CPU快速地在多條線程之間調度(切換)
- 如果CPU調度線程的時間足夠快,就造成了多線程並發執行的假象
思考:如果線程非常非常多,會發生什麼情況?
CPU會在N多線程之間調度,CPU會累死,消耗大量的CPU資源
每條線程被調度執行的頻次會降低(線程的執行效率降低)
多線程的優缺點
多線程的優點
- 能適當提高程序的執行效率
- 能適當提高資源利用率(CPU、內存利用率)
多線程的缺點
- 創建線程是有開銷的,iOS下主要成本包括:內核數據結構(大約1KB)、棧空間(子線程512KB、主線程1MB,也可以使用-setStackSize:設置,但必須是4K的倍數,而且最小是16K),創建線程大約需要90毫秒的創建時間
- 如果開啟大量的線程,會降低程序的性能
- 線程越多,CPU在調度線程上的開銷就越大
- 程序設計更加複雜:比如線程之間的通信、多線程的數據共享
2 多線程在iOS開發中的應用
什麼是主線程
- 一個iOS程序運行後,默認會開啟1條線程,稱為
「主線程」
或「UI線程」
- 一個iOS程序運行後,默認會開啟1條線程,稱為
主線程的主要作用
- 顯示刷新UI界面
- 處理UI事件(比如點擊事件、滾動事件、拖拽事件等)
主線程的使用注意
- 別將比較耗時的操作放到主線程中
- 耗時操作會卡住主線程,嚴重影響UI的流暢度,給用戶一種「卡」的壞體驗
iOS中多線程的實現方案
3. pthread 創建線程的簡單使用#import
// 子線程調用的方法
void * run(void *param)
{
for (NSInteger i = 0; i<50000; i++) {
NSLog(@"------buttonClick---%zd--%@", i, [NSThread currentThread]);
}
return NULL;
}
// 使用pthread 創建子線程並執行
- (IBAction)buttonClick:(id)sender {
pthread_t thread;
pthread_create(&thread, NULL, run, NULL);
pthread_t thread2;
pthread_create(&thread2, NULL, run, NULL);
}
4 NSThread4.1 一個NSThread對象就代表一條線程
- 創建、啟動線程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
- 主線程相關用法
+ (NSThread *)mainThread; // 獲得主線程
- (BOOL)isMainThread; // 是否為主線程
+ (BOOL)isMainThread; // 是否為主線程
- 獲得當前線程
NSThread *current = [NSThread currentThread];
- 線程的名字
- (void)setName:(NSString *)name;
- (NSString *)name;
4.2 其他創建線程的方式
- 創建線程後自動啟動線程
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
- 隱式創建並啟動線程
[self performSelectorInBackground:@selector(run) withObject:nil];
上述2種創建線程方式的優缺點
- 優點:簡單快捷
- 缺點:無法對線程進行更詳細的設置
4.3 線程的狀態
當一個線程被創建之後一共有 新建、就緒、運行、阻塞、死亡等幾種狀態。
當系統新創建一個子線程會將該線程放入到可調度線程池中,此時處於就緒狀態,當系統調度它執行任務的時候,它就處於一個運行狀態,如果該線程代用了sleep或加鎖之後,他就處於線程阻塞狀態,此時線程會被移出可調度線程池,當sleep到時或者得到同步鎖,線程又會解除阻塞狀態回到就緒狀態。當線程執行完任務之後被系統退出或者發生異常退出,就進入死亡狀態。進入死亡狀態就不能再次開啟任務
- 啟動線程
(void)start;
// 進入就緒狀態 -> 運行狀態。當線程任務執行完畢,自動進入死亡狀態
- 阻塞(暫停)線程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
+ // 進入阻塞狀態
- 強制停止線程
+ (void)exit;
// 進入死亡狀態
5 多線程的安全隱患
資源共享
- 1塊資源可能會被多個線程共享,也就是
多個線程可能會訪問同一塊資源
- 比如多個線程訪問同一個對象、同一個變數、同一個文件
- 1塊資源可能會被多個線程共享,也就是
當多個線程訪問同一塊資源時,很容易引發數據錯亂和數據安全問題
安全隱患實例 -- 存取錢 && 賣票
同一個賬戶,多線程同時操作
如圖,多個線程同時操作一個數據,導致 A 線程讀到數據尚未修改完成之前,另一個線程 B 也同時讀到了數據,當 B 要修改的時候,A 已經把原來的數據修改了,B 修改的數據依舊是之前的數據。這樣就導致了多線程操作同一個數據的數據混亂。
安全隱患分析圖示如下
安全隱患的解決
解決多線程的安全隱患,就加一個互斥鎖,當一個線程訪問並操作數據的時候,鎖住對應數據,防止其他線程訪問,當該線程訪問數據並操作完,放開互斥鎖,其他線程再進行訪問。
- 互斥鎖使用格式
@synchronized(鎖對象) { // 需要鎖定的代碼 }
注意:鎖定1份代碼只用1把鎖,用多把鎖是無效的
互斥鎖的優缺點
- 優點:能有效防止因多線程搶奪資源造成的數據安全問題
- 缺點:需要消耗大量的CPU資源
互斥鎖的使用前提:多條線程搶奪同一塊資源
相關專業術語:線程同步
線程同步的意思是:多條線程在同一條線上執行(按順序地執行任務)
互斥鎖,就是使用了線程同步技術
6 原子和非原子屬性
OC在定義屬性時有nonatomic和atomic兩種選擇
- atomic:原子屬性,為setter方法加鎖(默認就是atomic)
- nonatomic:非原子屬性,不會為setter方法加鎖
nonatomic和atomic對比
- atomic:線程安全,需要消耗大量的資源
- nonatomic:非線程安全,適合內存小的移動設備
iOS開發的建議
- 所有屬性都聲明為nonatomic
- 盡量避免多線程搶奪同一塊資源
- 盡量將加鎖、資源搶奪的業務邏輯交給伺服器端處理,減小移動客戶端的壓力
7 線程間通信
什麼叫做線程間通信 在1個進程中,線程往往不是孤立存在的,多個線程之間需要經常進行通信
線程間通信的體現
1個線程傳遞數據給另1個線程
在1個線程中執行完特定任務後,轉到另1個線程繼續執行任務
線程間通信常用方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
- 線程間通信實例-圖片下載
主線程需要展示圖片,圖片下載比較耗時,就放到子線程去操作。當子線程圖片下載完成後,回到主線程進行圖片賦值並展示。
小結本篇文章主要講解了多線程的一些基礎知識和 pthread 和 NSTread 兩種多線程方案。接下來會在下一篇文章中介紹 GCD 和 NSOpreation 的使用。
※View Components as Tag Helpers,離在線模板編輯又進一步
※淺談MVC Form認證
※asp.net core中負載均衡場景下http重定向https的問題
※原生JS+Canvas實現五子棋遊戲
※JAVA String 不可變性
TAG:科技優家 |
※BTC、ETH、EOS,安全、公平、效率
※ADA、ONT、EOS、AE對比及投資策略
※18年秀場錦集:TOM FORD,CHANNEL和JOHN VARVATOS
※為ZEN+新銳龍而生,信仰級X470主板駕到!華碩ROG CROSSHAIRⅦHERO首發開箱
※東芝發布CD5/XD5/HK6-DC系列NVMe SSD與KumoScale軟體
※[MD PHOTO]高庚杓趙在鉉等藝人出席tvN新劇 《CROSS》發布會
※AM4平台支持Ryzen APU!華碩、技嘉和華擎主板全線更新BIOS
※NAB上的羅德、ATOMOS、Wooden Camera
※俄勒岡州的希臘女神之三十:外場之王,NIKE ZOOM HYPERCHAOS X
※萬柚引力組-漫畫:ETH VS EOS,領略EOS之美
※福熙Talk Say PS教程:PHOTOSHOP製作梅花扇面效果
※男人的情懷之VOLVO V70 CROSS COUNTRY AWD
※英文美文:碩果與玫瑰RESULTS AND ROSES
※BOBOSNAP時裝精|探索英國本土設計師品牌(二)
※專訪TOS CEO,CTO:一個去中心化、安全可靠、快速透明的數據交換平台
※創意髮型:荷蘭 HANS BEERS-INTROSPECTIVE
※華麗大變身,KAWASAKI Z900RS 「THE GOOSE」
※吳一龍教授再亮劍,EGFR、ALK、ROS1基因聯合檢測新時代
※JOSHUA SANDERS 為全新鞋款 ZENITH 打造 Lookbook
※快傳開箱 AIR FOAMPOSITE PRO AS QS