一、 進程:
- 1.進程是一個具有一定獨立功能的程序關于某次數據集合的一次運行活動,它是操作系統分配資源的基本單元.
- 2.進程是指在系統中正在運行的一個應用程序,就是一段程序的執行過程,我們可以理解為手機上的一個app.
- 3.每個進程之間是獨立的,每個進程均運行在其專用且受保護的內存空間內,擁有獨立運行所需的全部資源
二、 線程
- 1.程序執行流的最小單元,線程是進程中的一個實體.
- 2.一個進程要想執行任務,必須至少有一條線程.應用程序啟動的時候,系統會默認開啟一條線程,也就是主線程
三、 進程和線程的關系
- 1.線程是進程的執行單元,進程的所有任務都在線程中執行
- 2.線程是 CPU 分配資源和調度的最小單位
- 3.一個程序可以對應多個進程(多進程),一個進程中可有多個線程,但至少要有一條線程
- 4.同一個進程內的線程共享進程資源
四、 多進程
打開mac的活動監視器,可以看到很多個進程同時運行
- 進程是程序在計算機上的一次執行活動。當你運行一個程序,你就啟動了一個進程。顯然,程序是死的(靜態的),進程是活的(動態的)。
- 進程可以分為系統進程和用戶進程。凡是用于完成操作系統的各種功能的進程就是系統進程,它們就是處于運行狀態下的操作系統本身;所有由用戶啟動的進程都是用戶進程。進程是操作系統進行資源分配的單位。
- 進程又被細化為線程,也就是一個進程下有多個能獨立運行的更小的單位。在同一個時間里,同一個計算機系統中如果允許兩個或兩個以上的進程處于運行狀態,這便是多進程。
五、 多線程
1.同一時間,CPU只能處理1條線程,只有1條線程在執行。多線程并發執行,其實是CPU快速地在多條線程之間調度(切換)。如果CPU調度線程的時間足夠快,就造成了多線程并發執行的假象
2.如果線程非常非常多,CPU會在N多線程之間調度,消耗大量的CPU資源,每條線程被調度執行的頻次會降低(線程的執行效率降低)
3.多線程的優點:
能適當提高程序的執行效率
能適當提高資源利用率(CPU、內存利用率)4.多線程的缺點:
開啟線程需要占用一定的內存空間(默認情況下,主線程占用1M,子線程占用512KB),如果開啟大量的線程,會占用大量的內存空間,降低程序的性能
線程越多,CPU在調度線程上的開銷就越大
程序設計更加復雜:比如線程之間的通信、多線程的數據共享
六、任務
就是執行操作的意思,也就是在線程中執行的那段代碼。在 GCD 中是放在 block 中的。執行任務有兩種方式:同步執行(sync)和異步執行(async)
- 同步(Sync):同步添加任務到指定的隊列中,在添加的任務執行結束之前,會一直等待,直到隊列里面的任務完成之后再繼續執行,即會阻塞線程。只能在當前線程中執行任務(是當前線程,不一定是主線程),不具備開啟新線程的能力。
- 異步(Async):線程會立即返回,無需等待就會繼續執行下面的任務,不阻塞當前線程。可以在新的線程中執行任務,具備開啟新線程的能力(并不一定開啟新線程)。如果不是添加到主隊列上,異步會在子線程中執行任務
七、隊列
隊列(Dispatch Queue):這里的隊列指執行任務的等待隊列,即用來存放任務的隊列。隊列是一種特殊的線性表,采用 FIFO(先進先出)的原則,即新任務總是被插入到隊列的末尾,而讀取任務的時候總是從隊列的頭部開始讀取。每讀取一個任務,則從隊列中釋放一個任務
在 GCD 中有兩種隊列:串行隊列和并發隊列。兩者都符合 FIFO(先進先出)的原則。兩者的主要區別是:執行順序不同,以及開啟線程數不同。
串行隊列(Serial Dispatch Queue):
同一時間內,隊列中只能執行一個任務,只有當前的任務執行完成之后,才能執行下一個任務。(只開啟一個線程,一個任務執行完畢后,再執行下一個任務)。主隊列是主線程上的一個串行隊列,是系統自動為我們創建的-
并發隊列(Concurrent Dispatch Queue):
同時允許多個任務并發執行。(可以開啟多個線程,并且同時執行任務)。并發隊列的并發功能只有在異步(dispatch_async)函數下才有效image
八、iOS中的多線程
主要有三種:NSThread、NSoperationQueue、GCD
1. NSThread:輕量級別的多線程技術
是我們自己手動開辟的子線程,如果使用的是初始化方式就需要我們自己啟動,如果使用的是構造器方式它就會自動啟動。只要是我們手動開辟的線程,都需要我們自己管理該線程,不只是啟動,還有該線程使用完畢后的資源回收
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testThread:) object:@"我是參數"];
// 當使用初始化方法出來的主線程需要start啟動
[thread start];
// 可以為開辟的子線程起名字
thread.name = @"NSThread線程";
// 調整Thread的權限 線程權限的范圍值為0 ~ 1 。越大權限越高,先執行的概率就會越高,由于是概率,所以并不能很準確的的實現我們想要的執行順序,默認值是0.5
thread.threadPriority = 1;
// 取消當前已經啟動的線程
[thread cancel];
// 通過遍歷構造器開辟子線程
[NSThread detachNewThreadSelector:@selector(testThread:) toTarget:self withObject:@"構造器方式"];
- performSelector...只要是NSObject的子類或者對象都可以通過調用方法進入子線程和主線程,其實這些方法所開辟的子線程也是NSThread的另一種體現方式。
在編譯階段并不會去檢查方法是否有效存在,如果不存在只會給出警告
//在當前線程。延遲1s執行。響應了OC語言的動態性:延遲到運行時才綁定方法
[self performSelector:@selector(aaa) withObject:nil afterDelay:1];
// 回到主線程。waitUntilDone:是否將該回調方法執行完在執行后面的代碼,如果為YES:就必須等回調方法執行完成之后才能執行后面的代碼,說白了就是阻塞當前的線程;如果是NO:就是不等回調方法結束,不會阻塞當前線程
[self performSelectorOnMainThread:@selector(aaa) withObject:nil waitUntilDone:YES];
//開辟子線程
[self performSelectorInBackground:@selector(aaa) withObject:nil];
//在指定線程執行
[self performSelector:@selector(aaa) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES]
需要注意的是:如果是帶afterDelay的延時函數,會在內部創建一個 NSTimer,然后添加到當前線程的Runloop中。也就是如果當前線程沒有開啟runloop,該方法會失效。在子線程中,需要啟動runloop(注意調用順序)
[self performSelector:@selector(aaa) withObject:nil afterDelay:1];
[[NSRunLoop currentRunLoop] run];
而performSelector:withObject:只是一個單純的消息發送,和時間沒有一點關系。所以不需要添加到子線程的Runloop中也能執行
2、GCD 對比 NSOprationQueue
我們要明確NSOperationQueue與GCD之間的關系
GCD是面向底層的C語言的API,NSOpertaionQueue用GCD構建封裝的,是GCD的高級抽象。
1、GCD執行效率更高,而且由于隊列中執行的是由block構成的任務,這是一個輕量級的數據結構,寫起來更方便
2、GCD只支持FIFO的隊列,而NSOperationQueue可以通過設置最大并發數,設置優先級,添加依賴關系等調整執行順序
3、NSOperationQueue甚至可以跨隊列設置依賴關系,但是GCD只能通過設置串行隊列,或者在隊列內添加barrier(dispatch_barrier_async)任務,才能控制執行順序,較為復雜
4、NSOperationQueue因為面向對象,所以支持KVO,可以監測operation是否正在執行(isExecuted)、是否結束(isFinished)、是否取消(isCanceld)
- 實際項目開發中,很多時候只是會用到異步操作,不會有特別復雜的線程關系管理,所以蘋果推崇的且優化完善、運行快速的GCD是首選
- 如果考慮異步操作之間的事務性,順序行,依賴關系,比如多線程并發下載,GCD需要自己寫更多的代碼來實現,而NSOperationQueue已經內建了這些支持
- 不論是GCD還是NSOperationQueue,我們接觸的都是任務和隊列,都沒有直接接觸到線程,事實上線程管理也的確不需要我們操心,系統對于線程的創建,調度管理和釋放都做得很好。而NSThread需要我們自己去管理線程的生命周期,還要考慮線程同步、加鎖問題,造成一些性能上的開銷
- 造成一些性能上的開銷
- 更多關于GCD:2019 iOS面試題-----多線程相關之GCD、死鎖、dispatch_barrier_async、dispatch_group_async、Dispatch Semaphore