帮你快速理解同步 ,异步,并发/并行,串行

本文深入解析了同步与异步、并行与并发的概念及其在多任务处理中的应用。通过具体的编程示例,展示了不同任务调度策略下程序执行的行为特征。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

同步:多个任务情况下,一个任务A执行结束,才可以执行另一个任务B。只存在一个线程。

异步:多个任务情况下,一个任务A正在执行,同时可以执行另一个任务B。任务B不用等待任务A结束才执行。存在多条线程。



接下来分析一下并行/并发,串行。很多人大概会混淆这些概念。



并发和并行其实是异步线程实现的两种形式。并行其实是真正的异步,多核CUP可以同时开启多条线程供多个任务同时执行,互补干扰,如上图的并行,其实和异步图例一样。但是并发就不一样了,是一个伪异步。在单核CUP中只能有一条线程,但是又想执行多个任务。这个时候,只能在一条线程上不停的切换任务,比如任务A执行了20%,任务A停下里,线程让给任务B,任务执行了30%停下,再让任务A执行。这样我们用的时候,由于CUP处理速度快,你看起来好像是同时执行,其实不是的,同一时间只会执行单个任务。

那么串行是什么呢,它是同步线程的实现方式,就是任务A执行结束才能开始执行B,单个线程只能执行一个任务,就如单行道只能行驶一辆车。

恩,到这里大家应该可以理解同步,异步,并行/并发,串行的概念了把~微笑

【并发编程包指在同一时间执行多个任务。又包含并行,和并发。并发不一定并行,但并行一定并发 】


  • 同步任务,使用dispatch_sync将任务加入队列。将同步任务加入串行队列,会顺序执行,一般不这样做并且在一个任务未结束时调起其它同步任务会死锁。将同步任务加入并行队列,会顺序执行,但是也没什么意义。
  • 异步任务,使用dispatch_async将任务加入队列。将异步任务加入串行队列,会顺序执行,并且不会出现死锁问题。将异步任务加入并行队列,会并行执行多个任务,这也是我们最常用的一种方式。
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • //同步任务加入串行队列
    NSLog(@"%@",[NSThread mainThread]);
    dispatch_queue_t queue = dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
         NSLog(@"同步任务1");
         NSLog(@"%@",[NSThread mainThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步任务2");
        NSLog(@"%@",[NSThread mainThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步任务3");
        NSLog(@"%@",[NSThread mainThread]);
    });
    2016-12-16 14:28:31.959 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
    2016-12-16 14:28:31.959 gcd测试[17007:717093] 同步任务1
    2016-12-16 14:28:31.959 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
    2016-12-16 14:28:31.959 gcd测试[17007:717093] 同步任务2
    2016-12-16 14:28:31.960 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
    2016-12-16 14:28:31.960 gcd测试[17007:717093] 同步任务3
    2016-12-16 14:28:31.960 gcd测试[17007:717093] <NSThread: 0x600000070a40>{number = 1, name = main}
    注意点:
    需要注意死锁问题,如果在上面的同步任务二中调用其他同步任务会死锁:
        dispatch_sync(queue, ^{
            NSLog(@"同步任务2");
            NSLog(@"%@",[NSThread mainThread]);
            dispatch_sync(queue, ^{
                NSLog(@"同步任务4");
                NSLog(@"%@",[NSThread mainThread]);
            });
        });
    因为任务4会在任务3中执行,然而串行队列一次只能执行一个任务,造成任务4等待任务3结束才能执行,然而任务3结束不了,因为任务4卡住了任务3执行,从而相互等待,造成死锁。
    

        //同步任务加入并行队列
        NSLog(@"%@",[NSThread mainThread]);
        dispatch_queue_t queue2 = dispatch_queue_create("concertqueue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_sync(queue2, ^{
            NSLog(@"同步任务1");
            NSLog(@"%@",[NSThread mainThread]);
        });
        dispatch_sync(queue2, ^{
            NSLog(@"同步任务2");
            NSLog(@"%@",[NSThread mainThread]);
        });
        dispatch_sync(queue2, ^{
            NSLog(@"同步任务3");
            NSLog(@"%@",[NSThread mainThread]);
        });
    2016-12-16 14:29:15.219 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
    2016-12-16 14:29:15.219 gcd测试[17027:724193] 同步任务1
    2016-12-16 14:29:15.219 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
    2016-12-16 14:29:15.220 gcd测试[17027:724193] 同步任务2
    2016-12-16 14:29:15.220 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
    2016-12-16 14:29:15.220 gcd测试[17027:724193] 同步任务3
    2016-12-16 14:29:15.220 gcd测试[17027:724193] <NSThread: 0x61000007e500>{number = 1, name = main}
    
    

        //异步任务加入串行队列
        NSLog(@"%@",[NSThread mainThread]);
        dispatch_queue_t queue3 = dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);
        dispatch_async(queue3, ^{
              NSLog(@"异步任务1");
              NSLog(@"%@",[NSThread mainThread]);
        });
        dispatch_async(queue3, ^{
            NSLog(@"异步任务2");
            NSLog(@"%@",[NSThread mainThread]);
        });
        dispatch_async(queue3, ^{
            NSLog(@"异步任务3");
            NSLog(@"%@",[NSThread mainThread]);
        });
    2016-12-16 14:30:36.040 gcd测试[17059:737939] <NSThread: 0x610000077980>{number = 1, name = main}
    2016-12-16 14:30:38.733 gcd测试[17059:738034] 异步任务1
    2016-12-16 14:30:38.734 gcd测试[17059:738034] <NSThread: 0x610000077980>{number = 1, name = (null)}
    2016-12-16 14:30:38.734 gcd测试[17059:738034] 异步任务2
    2016-12-16 14:30:38.734 gcd测试[17059:738034] <NSThread: 0x610000077980>{number = 1, name = (null)}
    2016-12-16 14:30:38.734 gcd测试[17059:738034] 异步任务3
    2016-12-16 14:30:38.734 gcd测试[17059:738034] <NSThread: 0x610000077980>{number = 1, name = (null)}
    
    

        //异步任务加入并行队列
        NSLog(@"%@",[NSThread mainThread]);
        dispatch_queue_t queue4 = dispatch_queue_create("concertqueue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue4, ^{
            NSLog(@"异步任务1");
            NSLog(@"%@",[NSThread mainThread]);
        });
        dispatch_async(queue4, ^{
            NSLog(@"异步任务2");
            NSLog(@"%@",[NSThread mainThread]);
        });
        dispatch_async(queue4, ^{
            NSLog(@"异步任务3");
            NSLog(@"%@",[NSThread mainThread]);
        });
    2016-12-16 14:25:54.894 gcd测试[16925:690820] <NSThread: 0x6100000696c0>{number = 1, name = main}
    2016-12-16 14:25:58.328 gcd测试[16925:690954] 异步任务1
    2016-12-16 14:26:01.805 gcd测试[16925:690959] 异步任务3
    2016-12-16 14:26:02.703 gcd测试[16925:690954] <NSThread: 0x6100000696c0>{number = 1, name = (null)}
    2016-12-16 14:26:02.703 gcd测试[16925:690975] 异步任务2
    2016-12-16 14:26:02.703 gcd测试[16925:690959] <NSThread: 0x6100000696c0>{number = 1, name = (null)}
    2016-12-16 14:26:02.704 gcd测试[16925:690975] <NSThread: 0x6100000696c0>{number = 1, name = (null)}
    配合这篇文章效果会更好:http://www.jianshu.com/p/bbabef8aa1fe

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值