GCD死锁与同步异步串行并行

目录

一、定义

1、队列

2、串行并行

3、同步异步

二、各种组合

1、同步串行:

2、异步串行

3、同步并行

4、异步并行

三、死锁

1、同步与主线程造成死锁

2、同步与某一线程造成死锁

3、主线程与循环


一、定义

1、队列

队列 queue 负责任务的调度,分为串行、并行、主队列,全局队列,队列的调度特点为先进先出,后加入的任务放在队尾。

2、串行并行

串行并行是指队列调度任务的方式,在创建queue时可以看到有两种方式:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

串行队列:一个任务执行完才能执行下一个任务。

并行队列:可以同时执行多个任务。

3、同步异步

同步异步指是否开辟新的线程,dispatch_async 与 dispatch_sync。

同步不会开辟新的线程,任务都是按顺序执行。

异步会开辟新的线程,任务可以同步执行。

二、各种组合

1、同步串行:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        NSLog(@" -- test --1"); // 任务1
    });
    NSLog(@" -- test --2"); // 任务2
    
    dispatch_sync(queue, ^{
        NSLog(@" -- test --3"); // 任务3
    });
    NSLog(@" -- test --4"); // 任务4

任务依次执行,打印为1,2,3,4

2、异步串行

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{
        NSLog(@" -- test --1"); // 任务1
    });
    NSLog(@" -- test --2"); // 任务2
    
    dispatch_async(queue, ^{
        NSLog(@" -- test --3"); // 任务3
    });
    NSLog(@" -- test --4"); // 任务4

因为是异步,所以是可以开辟线程同步执行的,不过因为是异步,所以1,3的顺序是固定的。任务2、4和1、3是的前后顺序是固定的,打印结果为2,1,4,3 或者2,4,1,3等组合。

3、同步并行

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_sync(queue, ^{
        NSLog(@" -- test --1"); // 任务1
    });

    NSLog(@" -- test --2"); // 任务2
    
    dispatch_sync(queue, ^{
        NSLog(@" -- test --3"); // 任务3
    });
    NSLog(@" -- test --4"); // 任务4

同步则不开启线程,所以并行没有什么作用,这里和同步串行一样,打印为1,2,3,4.

4、异步并行

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@" -- test --1"); // 任务1
    });

    NSLog(@" -- test --2"); // 任务2
    
    dispatch_async(queue, ^{
        NSLog(@" -- test --3"); // 任务3
    });
    NSLog(@" -- test --4"); // 任务4

异步并行是经常用到的,同时执行就没有规律了。

三、死锁

1、同步与主线程造成死锁

NSLog(@" -- test 1--");// 任务1
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@" -- test 2--");// 任务2
    });
    NSLog(@" -- test 3--");// 任务3

打印结果:1,

分析:执行完任务1以后,会来到一个同步线程,该线程做的是将任务2放到主线程队列中打印,但是放到主线程队列只能放到队尾,即任务3后面,所以如果想执行任务2需要先执行任务3,但因为是同步线程,只有执行完任务2才能执行任务3,最终造成死锁。

2、同步与某一线程造成死锁

dispatch_queue_t queue = dispatch_queue_create("queue", NULL);
    NSLog(@" -- test 1--");
    dispatch_sync(queue, ^{
        dispatch_sync(queue, ^{
            NSLog(@" -- test 3--");
        });
    });

与上个例子一样的形式。

3、主线程与循环

 NSLog(@" -- test 1--");// 任务1
    dispatch_async(dispatch_get_main_queue(), ^{
        
        NSLog(@" -- test 2--");// 任务2
    });
    while (1) {
    }
    NSLog(@" -- test 3--");// 任务3

结果:1,

分析:因为将任务2放到主线程队列,所以放到死循环后面,主线程在死循环中卡死,所以不会往下执行。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值