ios 面試題之多線程死鎖

死鎖

死鎖就是隊列引發的循環等待異步

一、一個比較常見的死鎖例子:主隊列同步async

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

在主線程中運用主隊列同步,也就是把任務放到了主線程的隊列中。
同步對於任務是馬上執行的,那麼當把任務放進主隊列時,它就會立馬執行,只有執行完這個任務,viewDidLoad纔會繼續向下執行。
而viewDidLoad和任務都是在主隊列上的,因爲隊列的先進先出原則,任務又需等待viewDidLoad執行完畢後才能繼續執行,viewDidLoad和這個任務就造成了相互循環等待,就形成了死鎖。
想避免這種死鎖,能夠將同步改爲異步dispatch_async,或者將dispatch_get_main_queue換成其餘串行或並行隊列,均可以解決。函數

二、一樣,下邊的代碼也會形成死鎖:spa

dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{
       
        dispatch_sync(serialQueue, ^{
            
            NSLog(@"deadlock");
        });
    });

外面的函數不管是同步仍是異步都會形成死鎖。
這是由於裏面的任務和外面的任務都在同一個serialQueue隊列內,又是同步,這就和上邊主隊列同步的例子同樣形成了死鎖
解決方法也和上邊同樣,將裏面的同步改爲異步dispatch_async,或者將serialQueue換成其餘串行或並行隊列,均可以解決線程

dispatch_queue_t serialQueue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    dispatch_queue_t serialQueue2 = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(serialQueue, ^{
       
        dispatch_sync(serialQueue2, ^{
            
            NSLog(@"deadlock");
        });
    });

這樣是不會死鎖的,而且serialQueue和serialQueue2是在同一個線程中的。code

相關文章
相關標籤/搜索