GCD死锁解析及相关API

2020-10-18  本文已影响0人  Jacob6666

前情提要

GCD极大地简化了平时开发中处理多线程问题的难度,但有时会遇上死锁,导致各种各样的问题,本文用简短的,通俗易懂的方式,与大家一起讨论如何分析死锁,了解了形成死锁的根本原因,问题也就迎刃而解。

正文内容

1. GCD


2. GCD的API:


3.GCD中的死锁:

强化几个概念:
熟悉了这几个概念,分析死锁就没难度了。
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_sync(mainQueue, ^{NSLog(@"1");});

mainQueue即为主线程,是一条serial Dispatch Queue,根据线程的定义,命令只能一条一条执行,不可以同时执行多条命令(因为执行ptr只有一个),而dispatch_sync(mainQueue, ^{NSLog(@"1");});要做的事,就是让主线程同时做两件事:1.执行dispatch_sync,将指定的Block同步地追加到主线程中,在追加Block结束之前,dispatch_sync函数会一直等待;2.执行主线程Block中的内容^{NSLog(@"1");},等待现在执行处理结束。结果互相等待造成死锁。如果我们将mainQueue换成自建的serialQueue就不会有这个问题,因为相当于两条线程,mainqueue中执行的是dispatch_sync的插入Block的操作,而执行Block的操作由我们自建的serialQueue搞定,所以就不存在死锁。

      dispatch_async(mainQueue, ^{
           NSLog(@"--1--");
       dispatch_sync(mainQueue, ^{
            NSLog(@"--2--");
        });});

--1--会被打印出来,--2--不会被打印出来,死锁道理同1。

dispatch_queue_t serialQueue1 = dispatch_queue_create("com.gcd.setTargetQueue2.serialQueue1", NULL);
dispatch_async(serialQueue1, ^{
           NSLog(@"--1--");
       dispatch_sync(serialQueue1, ^{
            NSLog(@"--2--");
        });});

这个仍然会死锁,道理同1,serialQueue1要同时处理两个问题,所以会死锁。--1--打印出来,--2--打印不出来。

对于Concurrent Dispatch Queueglobel queue因为"不等待现在执行中处理结束",意味着它可以不做任何等待地执行下去,所以不会引发死锁。

上一篇 下一篇

猜你喜欢

热点阅读