征服iOSiOS DevelopmentGCD相关

iOS基础篇-GCD死锁

2018-02-25  本文已影响207人  麦子_KB

GCD死锁概念:

使用GCD多线程编程时,如果同步函数dispatch_sync(),目标queue为当前queue,且queue为串行队列时,由于线程相互等待,会造成死锁,导致程序奔溃。

主线程运行如下代码:奔溃
 dispatch_sync(dispatch_get_main_queue(), ^{
     NSLog(@"queue");
 });
或者:
// 串行队列
dispatch_queue_t queue = dispatch_queue_create("test.concurrent", DISPATCH_QUEUE_SERIAL);
    
dispatch_sync(queue, ^{
   dispatch_sync(queue, ^{
        NSLog(@"bbb");
   });
});

原因分析如下:
dispatch_sync函数的目标队列为main_queue,而当前函数所在的队列也是main_queue。函数等待main_queue里block执行完成后才返回,而block任务加在当前main_queue队尾,block在等待dispatch_sync函数执行完成,它才会执行。相互等待造成block永远都无法执行,死锁导致程序奔溃。

解决办法:

1.目标queue和函数所在queue不相同

NSLog(@"aaa");
    
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"bbb");
        });
    });
    
NSLog(@"ccc");

2.queue为并行队列

NSLog(@"aaa");
    
// 并行队列
dispatch_queue_t queue = dispatch_queue_create("test.concurrent", DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(queue, ^{
    dispatch_sync(queue, ^{
       NSLog(@"bbb");
    });
});
    
NSLog(@"ccc");
上一篇 下一篇

猜你喜欢

热点阅读