進程: 系統(tǒng)正在運行的一個應用程序,每個進程之間是獨立的,互不干擾.
線程: 一個應用程序想要執(zhí)行任務,必須得有線程,么個進程至少要有一條線程. 線程是進程的基本執(zhí)行單元.(在進程中開辟線程,所有任務都是在線程中執(zhí)行)
線程
一個線程中任務的執(zhí)行是串行的,如果要在一個線程中執(zhí)行多個任務,那么只能一個一個地按順序執(zhí)行這些任務.
多線程: 一個進程中可以開啟多條線程,每條線程可以并行執(zhí)行不同的任務.
多線程:
多線程原理:
- 同一時間,CPU 只能處理一條線程,只有一條線程在工作
- 多線程并發(fā)執(zhí)行,其實是CPU 快速地在多條線程之間切換
- 如果CPU 調(diào)度線程的之間足夠快,救造成了多線程并發(fā)執(zhí)行的假象
多線程優(yōu)點:
- 提高程序的執(zhí)行效率
- 能適當提高資源利用率
多線程缺點:
- 開啟線程需要占用一定的內(nèi)存空間 (默認情況下,主線程占用512KB ,子線程占用512KB), 開啟大量線程,占用大量內(nèi)存空間,降低程序的性能.
- 線程越多,CPU 開銷越大
- 程序設計復雜,線程之間的通信,多線程的數(shù)據(jù)共享
iOS 中多線程的注意點
主線程:一個iOS 程序運行后,默認會開啟一條線程,稱為主線程.
* 顯示/刷新UI 界面
* 處理UI 事件 (點擊事件,滾動事件,拖拽事件)
* 不要將耗時的操作放到主線程中,會卡住主線程
* 不要同時開太多的線程 (1~3條即可,iOS中最多開5條線程)
子線程: 后臺線程,異步線程
iOS 多線程的實現(xiàn)方案
- pthread: C語言實現(xiàn),跨平臺,可移植,適用于Linux/Unix/windows系統(tǒng).需要程序員管理線程生命周期.
創(chuàng)建pthread 線程,需要導入頭文件phtread.h
//創(chuàng)建線程
pthread_t myRestrict;
/**
* 參數(shù)1: 線程地址
參數(shù)3: 線程中需要執(zhí)行的函數(shù)地址
*/
pthread_create(&myRestrict, NULL, run, NULL);
//NSThread 對象就代表一條線程
//方式1 : 需要手動開啟線程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
//開啟線程
[thread start];
//方式2: 線程自動開啟,不用手動開啟
[NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"http://c.gif"];
//方式3: 隱式創(chuàng)建線程
[self performSelector:@selector(download:) withObject:@"http://c.gif"];
//后臺子線程
[self performSelectorInBackground:@selector(download:) withObject:@"http://a.gif"];
//主線程
// [self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>];
//任意線程
// [self performSelector:<#(nonnull SEL)#> onThread:<#(nonnull NSThread *)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>];
- NSThread : OC語言實現(xiàn). 簡單易用,可以直接操作線程對象. 需要程序員管理線程生命周期.
- GCD: C語言實現(xiàn). 旨在替代NSThread 等線程技術. 系統(tǒng)自動管理線程生命周期.
- NSOperation: OC語言實現(xiàn). 基于GCD,比GCD多了一些簡單實用的功能. 系統(tǒng)自動管理線程生命周期.
- NSThread 實現(xiàn)多線程
一個NSThread 的對象,就代表一條線程
常見方法
//獲取當前線程
NSThread *current = [NSThread currentThread];
//獲取主線程
NSThread *main = [NSThread mainThread];
//判斷是否主線程
[NSThread isMainThread];
//線程睡眠
[NSThread sleepForTimeInterval:5]; //從本行代碼開始,線程休眠5秒
[NSThread sleepUntilDate:(NSDate *)date];
NSThread 的實例有一個name屬性,可以獲取當前想成的名字
[NSThread exit]; //銷毀當前線程
線程安全
為了方式多個線程搶奪同一個資源造成的數(shù)據(jù)安全問題
- 線程鎖--互斥鎖,多條線程搶奪同一塊資源的時候需要加鎖
格式: @synchronized () { }
優(yōu)點: 防止因多線程搶奪資源造成的數(shù)據(jù)安全問題
確定: 需要消耗大量的CPU資源
線程同步: 多條線程在同一條線上執(zhí)行 (按書序的執(zhí)行任務)
- 原子屬性和非原子屬性
OC在定義屬性是有nonatomic 和 atomic兩種選擇
atomic: 原子屬性,為setter方法加鎖(默認就是atomic),自動為該屬性加鎖,同一時間,只允許一條線程訪問該屬性
nonatomic: 非原子屬性,不會加鎖
注意: iOS中推薦使用nonatomic,因為atomic加鎖會消耗資源,適合內(nèi)存小的移動設備