GCD 之線程死鎖


GCD 確實好用 ,很強大,相比NSOpretion 無法提供 取消任務的功能。

如此強大的工具用不好可能會出現線程死鎖。 如下代碼:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"=================4");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"=================5");
    });
    NSLog(@"=================6");
}

 

GCD Queue 分為三種:

1,The main queue  :主隊列,主線程就是在個隊列中。

2,Global queues : 全局並發隊列。

3,用戶隊列:是用函數 dispatch_queue_create 創建的自定義隊列

 

dispatch_sync 和  dispatch_async 區別:

dispatch_async(queue,block)  async 異步隊列,dispatch_async 函數會立即返回, block會在后台異步執行。

dispatch_sync(queue,block)   sync 同步隊列,dispatch_sync 函數不會立即返回,及阻塞當前線程,等待 block同步執行完成。

 

分析上面代碼:

viewDidLoad 在主線程中, 及在
dispatch_get_main_queue() 中,執行到sync 時 向
dispatch_get_main_queue()插入 同步 threed1.

sync 會等到 后面block 執行完成才返回, sync 又再 dispatch_get_main_queue() 隊列中,
它是串行隊列,sync 是后加入的,前一個是主線程,
所以 sync 想執行 block 必須等待主線程執行完成,主線程等待 sync 返回,去執行后續內容。

照成死鎖,sync 等待mainThread 執行完成, mianThread 等待sync 函數返回。

下面例子:
- (void)viewDidLoad
{
    [super viewDidLoad];

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
    
    NSLog(@"=================1");
    
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"=================2");

    });
    NSLog(@"=================3");

    
});

}

 

程序會完成執行,為什么不會出現死鎖。

首先: async 在主線程中  創建了一個異步線程 加入  全局並發隊列,async 不會等待block 執行完成,立即返回,

1,async 立即返回, viewDidLoad 執行完畢,及主線程執行完畢。 
2,同時,全局並發隊列立即執行異步 block , 打印 1, 當執行到 sync 它會等待 block 執行完成才返回, 及等待
dispatch_get_main_queue() 隊列中的 mianThread 執行完成, 然后才開始調用block 。

因為1 和 2 幾乎同時執行,因為2 在全局並發隊列上, 2 中執行到sync 時 1 可能已經執行完成或 等了一會,mainThread 很快退出, 2 等已執行后續內容。

如果阻塞了主線程,2 中的sync 就無法執行啦,mainThread 永遠不會退出, sync 就永遠等待着,

- (void)viewDidLoad
{
    [super viewDidLoad];
dispatch_async(dispatch_get_global_queue(
0, 0), ^{ NSLog(@"=================1"); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"=================2"); }); NSLog(@"=================3"); }); NSLog(@"==========阻塞主線程"); while (1) { } NSLog(@"========2==阻塞主線程"); }

打印如下:

2014-11-30 17:56:22.296 Test[6108:379350] =================1

2014-11-30 17:56:22.296 Test[6108:379231] ==========阻塞主線程

永遠等着。。。。。

 

知道原理以后就會減少出錯啦。

 





 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM