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");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 目录(GCD): 关键词 混淆点 场景应用 总结 1. 关键词 线程概念: 独立执行的代码段,一个线程同时间只能执...
    Ryan___阅读 5,052评论 0 3
  • 简介 GCD(Grand Central Dispatch)是在macOS10.6提出来的,后来在iOS4.0被引...
    sunmumu1222阅读 4,375评论 0 2
  • 我们知道在iOS开发中,一共有四种多线程技术:pthread,NSThread,GCD,NSOperation: ...
    请叫我周小帅阅读 5,355评论 0 1
  • 一、GCD的API 1. Dispatch queue 在执行处理时存在两种Dispatch queue: 等待现...
    doudo阅读 3,411评论 0 0
  • 本文首发于我的个人博客:「程序员充电站」[https://itcharge.cn]文章链接:「传送门」[https...
    ITCharge阅读 349,922评论 308 1,927

友情链接更多精彩内容