iOS 多執行緒-學習

weixin_34146805發表於2018-05-02

學習多執行緒之前有些知識我們要了解一二。比如說程式、執行緒的概念等。

程式:

    程式是計算機中的程式關於某資料集合上的一次執行活動(可以理解為一個執行中的應用程式),是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。在早期面向程式設計的計算機結構中,程式是程式的基本執行實體;在當代面向執行緒設計的計算機結構中,程式是執行緒的容器。程式是指令、資料及其組織形式的描述,程式是程式的實體。(來源百度百科-程式

執行緒:

    執行緒有時被稱為輕量級程式,是程式執行流的最小單元。一個標準的執行緒由執行緒ID,當前指令指標暫存器集合和堆疊組成。另外,執行緒是程式中的一個實體,是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程式的其它執行緒共享程式所擁有的全部資源。執行緒是系統獨立排程和分派CPU的基本單位指令執行時的程式的排程單位。(來源百度百科-執行緒

iOS 多執行緒種類:

6454145-86be89f38ed4091d.png
圖 1

iOS 執行緒安全

當多個執行緒訪問同一塊資源時(資源競爭),很容易發生資料錯亂,資料發生安全隱患。就像好幾個人同一時間修改同一個資料,造成資料錯亂。

解決辦法:加鎖

1.互斥鎖: 

6454145-35c15ed87227cf87.png
圖 2

2.自旋鎖: automatic (耗效能)

NSThread 使用

1.alloc  2. 類方法 3. 隱式建立

6454145-8fd746d707e30ce7.png
圖 3

GCD 的使用

學習

GCD 首先得了解一下下面這些知識:

 任務(block):任務就是將要線上程中執行的程式碼,將這段程式碼用block封裝好,然後將這個任務新增到指定的執行方式(同步執行和非同步執行),等待CPU從佇列中取出任務放到對應的執行緒中執行。

同步(sync):一個接著一個,前一個沒有執行完,後面不能執行,不開執行緒。

非同步(async):開啟多個新執行緒,任務同一時間可以一起執行。非同步是多執行緒的代名詞

佇列:裝載執行緒任務的隊形結構。(系統以先進先出的方式排程佇列中的任務執行)。在GCD中有兩種佇列:序列佇列和併發佇列。

併發佇列:執行緒可以同時一起進行執行。實際上是CPU在多條執行緒之間快速的切換。(併發功能只有在非同步(dispatch_async)函式下才有效)

序列佇列:執行緒只能依次有序的執行。

GCD總結:將任務(要線上程中執行的操作block)新增到佇列(自己建立或使用全域性併發佇列),並且指定執行任務的方式(非同步dispatch_async,同步dispatch_sync)

注:同步是任務的依次執行,序列是佇列的依次執行。

我們經常遇到的 GCD 組合方式,如圖 4:

6454145-c98e344df9c686a2.png
圖 4

1. 序列同步 (不開啟新執行緒)

6454145-20f9a10f1cb6ea19.png
圖 5
6454145-6566eb3e61124f3d.png
圖 6 (執行結果圖)

2. 序列非同步 (會開啟新執行緒)

6454145-c885383384358d7e.png
圖 7
6454145-28174f4d56259c99.png
圖 8 (執行結果)

3. 併發同步 (不開啟新執行緒, 併發失效)

6454145-517bd126557d854d.png
圖 9
6454145-17e0ed6b5160ac81.png
圖 10 (執行結果)

4. 併發非同步 (開啟新執行緒)- 經常使用全域性併發佇列

6454145-282ca23caf43e90a.png
圖 11 (普通併發非同步)
6454145-4e0b5587d019c7b0.png
圖 12 (執行結果)

5. 主佇列同步 (死鎖)

6454145-905f017f1eec9433.png
圖 13

這裡要是放到主佇列中執行,就會GG。GG 的原因:1. 當列印完 A ,執行到 dispatch_sync 時,主執行緒得等 dispatch_sync  的 block  執行結束,但是 dispatch_sync 是加在主佇列的,它想獲取主執行緒執行block, (主執行緒等它,它又等主執行緒, 應該是這樣吧),這樣就形成了死鎖。 下面?這種情況一樣的道理,如圖 14:

6454145-8ea4d0417563cfe4.png
圖 14

6. 主佇列非同步 (不開啟新執行緒)

6454145-c3ed435aad9dfd34.png
圖 15
6454145-f759add9b1ba021d.png
圖 16(執行結果)

其他常用:

6454145-ff9e469c80cdd14e.png
6454145-606b1f5dc34a23f0.png
6454145-6c0f285fe2af0573.png

7. NSOperation 使用

  NSOperation 是 GCD 的高層封裝, 使用它只能使用它的子類。

1. 使用子類 NSInvocationOperation

2. 使用子類 NSBlockOperation

3. 定義繼承自 NSOperation 的子類,通過實現內部相應的方法來封裝任務。

注意:  NSInvocationOperation 如果只是通過(圖 17) 建立和 NSBlockOperation  如果只是通過 (圖 18)建立,並不會開啟新的執行緒,開啟新執行緒要把任務加入到佇列中 (NSOperationqueue),如圖 19 所示, 但是  NSBlockOperation 還有另一種比較簡單的方法,如圖 20 所示。

6454145-a3c2295b4252b356.png
圖 17 (NSInvocationOperation 使用)
6454145-b194159a8eb4addf.png
圖 18 (NSBlockOperation 使用)
6454145-956223db9245ca6e.png
圖 19 (NSOperationQueue 使用)
6454145-a982cd940f6a9ca0.png
圖 20 (NSBlockOperation 開啟新執行緒方法)





     最近在學習多執行緒,做一下筆記。如果有侵權,請聯絡刪除哦。不對的地方,希望各位大神,在評論區,指點迷經。非常感謝。最後感謝參考的博主們。。。下面是參考部落格。

iOS多執行緒:『GCD』詳盡總結 - CocoaChina_讓移動開發更簡單

iOS多執行緒全套:執行緒生命週期,多執行緒的四種解決方案,執行緒安全問題,GCD的使用,NSOperation的使用 - CocoaChina_讓移動開發更簡單

相關文章