iOS GCD死锁

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()时,会首先把dispatch_sync()函数放到当前线程的队列(就是主队列中),而且这个线程并不会立即返回,而是会等待block中的任务都完成时才会返回;
第二步:再把block中的任务依次放到主队列中等待执行;
由于是同步执行,而且block中的任务在主队列的线性表中的前面有个dispatch_sync()等待完成,而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");

你可能感兴趣的:(iOS GCD死锁)