多線程筆記-iOS進階必備,簡潔易懂,讓你對多線程有一個全新的認識

iOS中常見的多線程方案(後面三個的底層都是基於pthread)

技術方案

簡介

語言

線程生命週期

使用頻率

pthread

- 一套通用的多線程API

- 適用於Unix/Linux/Windows等系統

- 跨平臺/可移植

- 使用難度大

C

程序員管理

幾乎不用

NSThread

- 使用更加面向對象

- 簡單易用,可直接操作線程對象

OC

程序員管理

偶爾使用

GCD

- 旨在替代NSThread等線程技術

- 充分利用設備的多核

C

自動管理

經常使用

NSOperation

- 基於GCD(底層是GCD)

- 比GCD多了一些更簡單實用的功能

- 使用更加面向對象

OC

自動管理

經常使用

 

GCD的常用函數 GCD中有2個用來執行任務的函數 1、用同步的方式執行任務 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); - queue:隊列 - block:任務 2、用異步的方式執行任務 dispatch_async(dispatch_queue_t queue, dispatch_block_t block); GCK源碼:https://github.com/apple/swift-corelibs-libdispatch

 

GCD的隊列 GCD的隊列可以分爲2大類型 1、併發隊列(Concurrent Dispatch Queue) - 可以讓多個任務併發(同時)執行(自動開啓多個線程同時執行任務) - 併發功能只有在異步(dispatch_async)函數下才有效 2、串行隊列(Serial Dispatch Queue) - 讓任務一個接着一個地執行(一個任務執行完畢後,再執行下一個任務)

 

容易混淆的術語 有4個術語比較容易混淆:同步、異步、併發、串行 1、同步和異步主要影響:能不能開啓新的線程 - 同步:在當前線程中執行任務,不具備開啓新線程的能力 - 異步:在新的線程中執行任務,具備開啓新的線程的能力 2、併發和串行主要影響:任務的執行方式 - 併發:多個任務併發(同時)執行 - 串行:一個任務執行完畢後,再執行下一個任務

 

 

併發隊列

手動創建的串行隊列

主隊列

同步(sync)

- 沒有開啓新線程

- 串行執行任務

- 沒有開啓新線程

- 串行執行任務

- 沒有開啓新線程

- 串行執行任務

異步(async)

- 有開啓新線程

- 併發執行任務

- 有開啓新線程

- 串行執行任務

- 沒有開啓新線程

- 串行執行任務

  • 使用sync函數往當前串行隊列中添加任務,會卡住當前的串行隊列(產生死鎖)
  • 主隊列其實也是一個串行隊列,(queue:隊列)
  • dispatch_sync:立馬在當前線程執行任務,執行完畢後才能繼續往下執行

- (void)viewDidLoad { [super viewDidLoad]; //問題:以下代碼是在主線程執行的,會不會產生死鎖?會! NSLog(@"執行任務1"); //隊列的特點:排隊,FIFO: First In First Out,先進後出。 dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_sync(queue, ^{ NSLog(@"執行任務2"); }); //dispatch_sync: 立馬在當前線程執行任務,執行完畢後才能繼續往下執行 NSLog(@"執行任務3"); }

 

- (void)viewDidLoad { [super viewDidLoad]; //問題:以下代碼是在主線程執行的,會不會產生死鎖?不會! NSLog(@"執行任務1"); //隊列的特點:排隊,FIFO: First In First Out,先進後出。 dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_async(queue, ^{ NSLog(@"執行任務2"); }); //dispatch_async: 不要求立馬在當前線程同步執行任務 NSLog(@"執行任務3"); }

 

併發隊列:系統創建的:dispatch_get_global_queue(0, 0):這是全局併發隊列是系統創建好的併發隊列可以直接調用,你也可以自己創建併發隊列或者串行隊列。全局併發隊列只有一個,也就是不管你調用多少次都是同一個,指針地址都是一樣的。但是自己創建的併發隊列是不同的

併發隊列:自己創建的:dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);

串行隊列:自己創建的:dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL);

 

死鎖:併發隊列裏面不管有多少個任務都可以同時執行,不存在誰等誰的問題

串行隊列裏面如果有多個任務必須要等前一個任務執行完才能執行後一個任務,所以如果後一個任務包含前一個任務的一部分,那麼就會產生死鎖。因爲前一個任務裏有一部分在第二個任務所以要去執行第二個任務,但是第二個任務必須等前一個任務執行完才能執行,所以你等我我等你就造成了死鎖。

總結:使用sync函數往當前串行隊列中添加任務,會卡住當前串行隊列(產生死鎖)。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章