1.什么是進(jìn)程窑睁,什么是線程?
進(jìn)程是一個正在運行的應(yīng)用程序葵孤,一個應(yīng)用程序可以對應(yīng)一個或多個進(jìn)程担钮。應(yīng)用程序是一個沒有生命的實體,只有運行以后尤仍,才能稱為一個活動的實體箫津,也就是進(jìn)程。
進(jìn)程是操作系統(tǒng)分配資源的基本單元宰啦。進(jìn)程在運行的過程中擁有獨立的內(nèi)存單元苏遥,一個進(jìn)程崩潰后,不會對其他進(jìn)程造成影響绑莺。
線程是獨立運行和獨立調(diào)度的基本單位暖眼,線程才是程序真正的執(zhí)行單元負(fù)責(zé)代碼的執(zhí)行。一個進(jìn)程可以有一個或多個線程纺裁,同一個進(jìn)程的線程共享進(jìn)程的內(nèi)存資源。線程沒有單獨的地址空間司澎,一個線程崩潰整個進(jìn)程就會崩潰欺缘。
2.什么是多線程?
多線程的實現(xiàn)原理:事實上挤安,同一時間內(nèi)單核的CPU只能執(zhí)行一個線程谚殊,多線程是CPU快速的在多個線程之間進(jìn)行切換(調(diào)度),造成了多個線程同時執(zhí)行的假象蛤铜。
如果是多核CPU就真的可以同時處理多個線程了嫩絮。
多線程的目的是為了同步完成多項任務(wù),通過提高系統(tǒng)的資源利用率來提高系統(tǒng)的效率围肥。
3.多線程有什么優(yōu)點和缺點剿干?
多線程可以提高系統(tǒng)的資源利用率,從而提高系統(tǒng)的效率穆刻。
開啟多線程需要花費時間和空間置尔,開啟過多的線程反而會降低性能,cpu頻繁的在多個線程中調(diào)度會消耗大量的CPU資源氢伟,把CPU累死榜轿。所以幽歼,不要在系統(tǒng)中同時開啟過多的子線程。
4.線程創(chuàng)建實際的開銷在內(nèi)存方面是有多大谬盐?
蘋果官方文檔說甸私,開啟線程需要消耗內(nèi)存資源和性能。每一個線程都需要分配系統(tǒng)內(nèi)核空間和程序的內(nèi)存空間飞傀。
Each thread requires the allocation of memory in both the kernel memory space and your program’s memory space. The core structures needed to manage your thread and coordinate its scheduling are stored in the kernel using wired memory. Your thread’s stack space and per-thread data is stored in your program’s memory space.
下面是一張具體的圖:
簡單來說颠蕴,創(chuàng)建線程需要花費大約90微秒的時間和512KB的棧空間助析,以及1KB的內(nèi)核空間犀被。
參考:官方文檔
5.多線程在開發(fā)中的使用場景?
在實際開發(fā)中應(yīng)該將一些耗時的操作放在子線程執(zhí)行外冀,iOS中默認(rèn)有一個主線程寡键,用來響應(yīng)用戶的手勢和刷新UI,如果在主線程執(zhí)行耗時操作就會把頁面卡死雪隧,直到執(zhí)行完了這個操作才能操作界面西轩。一定要在主線程刷新UI的原因:iOS為了保證效率,多線程是線程不安全的脑沿,在子線程刷新UI可能會導(dǎo)致未知錯誤藕畔。
6.iOS中實現(xiàn)多線程的幾種方案,各自有什么特點庄拇?
Pthread 是用c語言實現(xiàn)的注服,非常底層的多線程實現(xiàn)方案,在開發(fā)中很少用到措近。需要程序員手動管理線程的生命周期(手動創(chuàng)建和銷毀)溶弟。
NSThread 面向?qū)ο蟮模枰绦騿T手動創(chuàng)建線程瞭郑,但不需要手動銷毀辜御。子線程間通信很難。
創(chuàng)建子線程:
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testThread:) object:@"我是參數(shù)"];//有返回值屈张,可以拿到返回值設(shè)置線程的優(yōu)先級和名稱
[thread start];//需要手動開啟
[NSThread detachNewThreadSelector:@selector(testThread:) toTarget:self withObject:@"便利構(gòu)造器方式"];//沒有返回值擒权,不需要手動開啟
[self performSelectorInBackground:@selector(run:)withObject:@"開啟后臺線程"];//沒有返回值,不需要手動開啟阁谆,只要是NSObject對象或者是NSObject的子類對象都可以用這種方法開啟子線程碳抄,用下面的方法回到主線程
回到主線程:
[self performSelectorOnMainThread:@selector(backMainThread) withObject:nil waitUntilDone:YES];//回到主線程的方法
GCD c語言,充分利用了設(shè)備的多核笛厦,自動管理線程生命周期纳鼎。比NSOperation效率更高。
gcd的用法很多,不寫了贱鄙。
參考:gcd劝贸、關(guān)于iOS多線程看我就夠了
NSOperation 基于gcd封裝,更加面向?qū)ο蠖耗萭cd多了一些功能映九。
兩個概念:操作(NSOperation)和隊列(NSOperationQueue)
創(chuàng)建隊列:
NSOperationQueue*mainQueue = [NSOperationQueuemainQueue];//創(chuàng)建主隊列,串行隊列
NSOperationQueue*queue = [[NSOperationQueue alloc]init];//創(chuàng)建非主隊列瞎颗,同時具備串行隊列和并發(fā)隊列的功能件甥。可以設(shè)置最大并發(fā)數(shù)哼拔,實現(xiàn)串行和并行的功能引有。
創(chuàng)建任務(wù)
NSInvocationOperation* opt1 = [[NSInvocationOperation alloc]initWithTarget:selfselector:@selector(task1)object:nil];
[queueaddOperation:opt1];//不需要手動啟動隊列
NSBlockOperation*blockOperation = [NSBlockOperationblockOperationWithBlock:^{NSLog(@"block --- %@",[NSThreadcurrentThread]); }];
[queue addOperation:blockOperation];
也可以不創(chuàng)建任務(wù),直接用block向隊列添加任務(wù):
[mainQueue addOperationWithBlock:^{ ? ? ? ? ??
self.myImage.image= image;
?NSLog(@"ui-------%@",[NSThreadcurrentThread]);
?}];
NSOperation一些特有的用法: