簡介
一個必不可少的知識,時間久了,一位小夥伴遇到疑問時,我竟然解答混淆了,當然重寫溫習一下,不管是新知識也好,基本概念也好,知識就是在不斷的咀嚼中不斷理解,於是寫了一篇對應多線程和網絡自己的理解,有理解不恰當的地方,請提出,謝謝大家
多線程概念
1.異步與同步
異步:多個任務操作可以同時執行適應傳輸數據量大,在連接過程中UI不“凍結”;
同步:代碼從上到下,按順序依次一步一步的執行,當請求的數據量小時,同步連接是一個很好的選擇。UI“凍結”是它的一個缺點。
2.進程與線程
進程:進程是系統中正在運行的一個程序,每一個進程都是獨立的,都運行在其專用且受保護的內存空間內,通過活動監視器可以查看mac系統中所有開啓的進程
線程:線程是進程的基本執行單元,進程的所有任務都在線程中執行,一個進程至少要有一條線程,當程序啓動時會默認開啓一條線程,這條線程被稱爲主線程或者UI線程
3.之間關係
一個進程可以開啓多條線程,每一條線程都可以執行不同的任務
進程--->小工廠
線程--->員工
主線程--->老闆
多線程技術可以提升程序執行的效率
4.主線程
程序啓動創建的線程被稱爲主線程
作用:顯示/刷新UI界面;處理UI事件:點擊\滾動\拖拽等事件
注意:要將耗時操作放在後臺執行,否則會影響UI的流暢度,破壞用戶體驗;所有的網絡訪問都是耗時操作
多線程原理
1.使用多線程目的:將耗時操作放在後臺去執行,待執行完成後,通知主線程更新UI
2.原理:
單核CPU:同一時間,CPU只能處理一個線程,換而言之,在同一時間內只有一個線程在執行
多線程同時執行:CPU快速的在多個線程間的切換;CPU調度線程的時間足夠快,就造成了多線程同時執行的效果
如果線程非常多的時候:CPU會在N個線程之間切換,消耗大量的CPU資源,每一條線程調度的次數會降低,線程的執行效率也會降低
3.多線程的優缺點
優點:可以適當提高程序的執行效率;提高資源的利用率(CPU,內存)
缺點:開啓線程需要佔用一定的內存空間(默認情況下,每一條線程都佔512KB--iOS8.0後主線程默認的堆棧也是512KB)
如果開啓大量的線程,會佔用大量的空間,降低程序的性能,那麼CPU在調度線程上的開銷就越大
線程是程序邏輯思維更爲複雜;比如線程間的通訊及多線程的數據共享
4.多線程的實現方案
pthread演練
1.基本概念
pthread是POSIX多線程開發框架,是跨平臺的C語言框架,在蘋果的頭文件中並沒有太多的註釋
2.演練
// 創建線程,並且在線程中執行 demo 函數
- (void)pthreadDemo {
/** 參數:
1> 指向線程標識符的指針,C 語言中類型的結尾通常 _t/Ref,而且不需要使用 *
2> 用來設置線程屬性
3> 新建立的線程執行代碼的函數
4> 運行函數的參數 返回值: - 若線程創建成功,則返回0 - 若線程創建失敗,則返回出錯編號 */
pthread_t threadId =NULL;
NSString *str =@"Hello Pthread";
int result = pthread_create(&threadId,NULL, demo, (__bridgevoid *)(str));
if (result ==0) {
NSLog(@"創建線程 OK");
}else {
NSLog(@"創建線程失敗 %d", result);
}
}
// 後臺線程調用函數
void *demo(void *params) {
NSString *str = (__bridgeNSString *)(params);
NSLog(@"%@ - %@", [NSThread currentThread], str);returnNULL;
}
小結:
在C語言中並沒有對象的概念,對象是以結構體的方式來實現的;C語言中的void*和OC中的id是等價的;混合開發時,如果在C和OC之間進行數據傳遞,需要用_bridge進行橋接,橋接的目的是爲了告訴編譯器如何管理內存
NSThread演練
三種創建方式
NSThread的對象方法
- (void)threadDemo1 {
NSLog(@"before %@", [NSThread currentThread]);
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(longOperation:) object:@"THREAD"];
[thread start];
NSLog(@"after %@", [NSThread currentThread]);}
小結:在start方法執行完畢後,會在另一個線程執longOperation:方法
NSThread的類方法
- (void)threadDemo2 {
NSLog(@"before %@", [NSThread currentThread]);
[NSThread detachNewThreadSelector:@selector(longOperation:) toTarget:self withObject:@"DETACH"];
NSLog(@"after %@", [NSThread currentThread]);
}
小結:detachNewThreadSelector:類方法不需要啓動;會自動創建線程並執行@selector方法
NSThread的類方法
- (void)threadDemo3 {
NSLog(@"before %@", [NSThread currentThread]);
[self performSelectorInBackground:@selector(longOperation:) withObject:@"PERFORM"];
NSLog(@"after %@", [NSThread currentThread]);
}
小結:這是NSObject的分類方法,會在後臺自動執行@selector方法;
線程的狀態
狀態說明
a.新建
實例化線程對象
b.就緒
向線程對象發送start消息,線程對象被加入可調度線程池等待CPU調度;detach方法和performSelectorInBackGround方法會直接實例化一個線程對象並加入可調度線程池
c.運行
CPU負責調度可調度線程池中的任務執行
線程執行完之前,狀態可能在就緒和運行之間來回切換
d.阻塞
當滿足某個預定條件時可以,可以使用休眠或鎖阻塞線程執行
sleepForTimeInterval:休眠指定時長
sleepUntilDate:休眠到指定日期
@synchronized(self):互斥鎖
e.死亡
正常死亡:線程執行完畢
非正常死亡:當滿足某個條件時,在線程內部終止執行;當滿足某個條件時在主線程終止線程對象
網絡的基本概念
1.基本概念
客戶端:client,移動應用(iOS/android)
服務器:server,爲客戶端提供服務,提供數據,提供資源的特殊的計算機
請求:request,客戶端向服務器索取數據的一種行爲
響應:response,服務器對客戶端的請求作出的一系列反應,一般指返回數據給客戶端
網絡的核心是請求和響應!
2.服務器
爲客戶端提供數據的特殊計算機
按照軟件開發階段來分,服務器分爲以下兩種
1> 遠程服務器:
別名:外網服務器,正式服務器
使用階段:應用上線後使用的服務器
使用人羣:全體用戶使用
速度:取決於服務器的性能,用戶的網速
2>本地服務器
別名:內務服務器,測試服務器
使用階段:應用處於開發,測試階段使用的服務器
使用人羣:僅供內部人員使
速度:由於是局域網,所以速度飛快,有助於提高開發測試效率