GCD线程死锁

GCD简化了多线程的使用,但使用不当会导致线程死锁。

dispatch_async(queue,block) async 异步队列,dispatch_async 函数会立即返回, block会在后台异步执行。
dispatch_sync(queue,block) sync 同步队列,dispatch_sync 函数不会立即返回,及阻塞当前线程,等待 block同步执行完成。
例1.

//线程死锁
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"线程死锁1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"线程死锁2");
    });
    NSLog(@"线程死锁3");

}

//打印结果 线程死锁1

在主线程中调用主线程的同步方法就会导致线程死锁。
上面在执行完第一个log后,在主线程中插入block等待执行,而主线程此时正等待block执行完返回,导致死锁。

例2.

- (void)viewDidLoad {
    [super viewDidLoad];      
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"=================1");
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"=================2")
       });
        NSLog(@"=================3");
    });
    NSLog(@"=================4");

}

//打印结果 
//=================4
//=================1
//=================2
//=================3

在子线程中调用主线程的同步方法不会造成死锁
第一步在全局队列里调用异步方法,不会等block执行直接返回,所以先打印4,随后执行block,打印1,然后在主线程中插入打印2命令,因为这时主线程已经执行完成,所以可以打印2,打印2block执行完成之后返回,继续执行打印3,结束

例3.

- (void)viewDidLoad {
    [super viewDidLoad];   
     dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"=================1");
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"=================2");
        });
        NSLog(@"=================3");
    });
    NSLog(@"=================4");
    while (1) {
    }
    NSLog(@"=================5");
}

//打印结果
//=================4
//=================1

第一步在全局队列里调用异步方法,不会等block执行直接返回,所以先打印4,然后碰到死循环,主线程被卡住,不能执行打印5,随后执行block,执行打印1,然后在主工程调用同步方法,在主工程插入block,而此时主线程在死循环中,block无法执行,导致无法返回,打印3无法执行,bomb

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