[死鎖] dispatch_sync 之於 當前線程

1: dispatch_sync 是指在指定 線程隊列queue 同步執行任務blockdispatch_sync具有等待block執行結束再能回調的特點

void
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);


因此,使用dispatch_sync的時候,需要注意啦,不要在當前線程隊列,執行block任務,

不然會死鎖!!!!dead-lock!!!!!


爲什麼呢?下面用Viewcontroller具體代碼展示  !


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    NSLog(@"Hello 1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"Hello 2");
    });
    NSLog(@"Hello 3");
}

這個會怎麼輸出呢?------答案是:Hello 1 ,而且輸出這個後,App會進入死鎖,任何點擊都沒響應!

解析:

當代碼 在主線程 執行到dispatch_sync塊代碼(在主線程壓入這行代碼進行執行),

但是執行這代碼,不能馬上執行結束回調,而是等待(這行代碼繼續壓在隊列中),

然後又在當前隊列壓入block 任務,而block任務也不能被執行,因爲dispatch_sync代碼塊

先執行(FIFO)且未執行結束,所以block需要等待dispatch_sync,但是dispatch_sync具有等待block執行結束再能回調的特點

就這樣,他們互相等待對方,因此死鎖!


因此,不要dispatch_sync把block壓入當前隊列,對於這樣代碼,我們可以這樣寫:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 這裏當前線程是主線程,
    dispatch_queue_t myQueue = dispatch_queue_create("MyQueue", NULL);
    
    NSLog(@"Hello 1");
    dispatch_sync(myQueue, ^{
        NSLog(@"Hello 2");
    });
    NSLog(@"Hello3");
    
}

這樣就會輸出:

Hello 1

Hello 2

Hello 3


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