GCD线程死锁问题详细解读与dispatch_set_target_queue的使用

本篇文章适合有一定线程概念新手请移步.

GCD线程死锁

经典例题
dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"线程"); });

首先先要明白造成死锁的条件之一就是当前线程必须为串行队列.并行队列不存在死锁问题.然后就是dispatch_sync所在队列必须和当前线程所在队列必须是同一队列.才会造成死锁.首先我们假定不是在同一队列,假如当前线程所在队列为queue0,dispatch_sync所在队列为queue1.当执行dispatch_sync时,它会先去阻塞当前线程也就是queue0,然后再去执行queue1.当dispatch_sync的block执行完毕后,系统才会继续执行queue0.当queue0与queue1为统一队列时.dispatch_sync会放在队列最后,而且还会阻塞当前线程,而当前队列为串行队列顺序执行,只会分配一个线程.就会造成线程死锁.打个比方有一群人过河 ,串行队列相当于单人通过规则,线程相当于独木桥,只能单行通过,dispatch_sync相当于特殊人员有优先通过的权利.但是他只能排在队尾.他又想第一个过去.最终导致大家都过不了河.

dispatch_set_target_queue使用

diapatch_set_target_queue的作用就是解决多个多个串行队列无法按顺序执行问题

实例代码

dispatch_queue_t targetQueue = dispatch_queue_create("test.target.queue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue3 = dispatch_queue_create("test.3", DISPATCH_QUEUE_SERIAL);
    dispatch_set_target_queue(queue1, targetQueue);
    dispatch_set_target_queue(queue2, targetQueue);
    dispatch_set_target_queue(queue3, targetQueue);
    dispatch_async(queue1, ^{
        NSLog(@"1 in");
        [NSThread sleepForTimeInterval:3.f];
        NSLog(@"1 out");
    });
    dispatch_async(queue2, ^{
        NSLog(@"2 in");
        [NSThread sleepForTimeInterval:2.f];
        NSLog(@"2 out");
    });
    dispatch_async(queue3, ^{
        NSLog(@"3 in");
        [NSThread sleepForTimeInterval:1.f];
        NSLog(@"3 out");
    });

打印数据

2019-05-21 13:07:26.910186+0800 offerPlan[2507:122740] 1 in
2019-05-21 13:07:29.912428+0800 offerPlan[2507:122740] 1 out
2019-05-21 13:07:29.912887+0800 offerPlan[2507:122740] 2 in
2019-05-21 13:07:31.914646+0800 offerPlan[2507:122740] 2 out
2019-05-21 13:07:31.914965+0800 offerPlan[2507:122740] 3 in
2019-05-21 13:07:32.919780+0800 offerPlan[2507:122740] 3 out

注释掉dispatch_set_target_queue或者将targetQueue改成并行队列
打印数据

2019-05-21 13:06:31.923109+0800 offerPlan[2484:121852] 1 in
2019-05-21 13:06:31.923122+0800 offerPlan[2484:121853] 3 in
2019-05-21 13:06:31.923109+0800 offerPlan[2484:121851] 2 in
2019-05-21 13:06:32.927346+0800 offerPlan[2484:121853] 3 out
2019-05-21 13:06:33.926678+0800 offerPlan[2484:121851] 2 out
2019-05-21 13:06:34.927536+0800 offerPlan[2484:121852] 1 out

你可能感兴趣的:(GCD线程死锁问题详细解读与dispatch_set_target_queue的使用)