多线程 死锁 , dispatch_barrier_async和dispatch_barrier_sync

为了深刻理解死锁和栅栏我写了如下两段程序,这两段程序的结果分别如何勒

dispatch_queue_t queue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_SERIAL);

    dispatch_async(queue, ^{

    dispatch_async(queue, ^{

            NSLog(@"任务0");

        });

        dispatch_barrier_async(queue, ^{

            NSLog(@"任务1");

        });

        dispatch_async(queue, ^{

            NSLog(@"任务2");

        });

        NSLog(@"任务3");

    });


    dispatch_async(queue, ^{

        dispatch_barrier_sync(queue, ^{

            NSLog(@"任务4");

        });

        dispatch_async(queue, ^{

            NSLog(@"任务5");

        });

        NSLog(@"任务6");

    });


2018-03-05 19:01:29.962166+0800 Demo[80986:6088486] 任务3

2018-03-05 19:01:29.962375+0800 Demo[80986:6088486] 任务0

2018-03-05 19:01:29.962483+0800 Demo[80986:6088486] 任务1

2018-03-05 19:01:29.962720+0800 Demo[80986:6088486] 任务2

运行起来可以看到第一段程序打印的是3 ,0,1, 2,第二段程序crash了,为什么会产生这样的结果勒

首先说下为什么会crash ,因为我定义的queue是串形队列,主要问题出在  dispatch_barrier_sync(queue, ^{  })会把block中的任务添加到queue的队列的尾部,而我外面包的 dispatch_async(queue, ^{  })block就是在这个queue中执行的,所以block的内容会在任务6执行完了才会执行,而sync又会把当前队列给堵塞住,所以crash了,跟这段代码一样     dispatch_sync(dispatch_get_main_queue(), ^{    });,主线程也是串形队列,所以crash。

那么第一段程序中为什么一定是3012,这是因为我外面包的一层block是queue中执行,所以后面的block都会在任务3之后执行,由于栅栏的作用,后面三个的顺序一定是012,所以最后的结果就是3012.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 文 || 張贺 进程: 进程是指在系统中正在运行的一个应用程序。每个进程之间是独立的,每个进程均运行在其专用且受保...
    張贺阅读 2,338评论 0 4
  • 多线程安全问题的原因: 通过图解:发现一个线程在执行多条语句时,并运算同一个数据时,在执行过程中,其他线程参与进来...
    烟雨平生X阅读 1,449评论 0 0
  • 1. 多线程的底层实现 (1)首先什么是线程 1个进程要想执行任务,必须得有线程.线程是进程的基本执行单元,一个进...
    AI_Eleven阅读 4,809评论 0 3
  • GCD,全称是Grand Central Dispatch,纯C语言,是苹果公司为多核的并行运算提出的解决方案,它...
    估唔到阅读 1,267评论 2 1
  • 游客大概有三种: 一种在石头上刻上“到此一游” 一种在镜头上刻上“到此一游” 一种在心头上刻上“到此一游”
    iSteven阅读 2,463评论 0 0