美文网首页
浅谈GCD的线程依赖

浅谈GCD的线程依赖

作者: 尼克Nick | 来源:发表于2018-04-09 17:00 被阅读0次

    之前对线程使用的不是太多,今天专门抽时间看了下GCD的线程使用。好记性不如烂笔头,整理下来方便以后复习使用,也与和大家分享一下。第一次写简书,水平有限,欢迎大家多多给出建议,互相学习。成长的路上,与大家同勉~~~~

    下面进入正题

    需求举例:有三个任务需要顺序执行:任务1-->任务2-->任务3

    实现方式一:(线程组)

    ①.创建线程组:dispatch_group_t group = dispatch_group_create();

    ②.创建队列:dispatch_queue_t queue = dispatch_queue_create(0, 0);

    ③.把任务提交到队列中执行:dispatch_group_enter(group);

                                                    dispatch_async(queue, ^{

                                                            [NSThread sleepForTimeInterval:2];

                                                            NSLog(@"任务1执行");

                                                            dispatch_group_leave(group);

                                                    });

                                                    dispatch_barrier_async(queue, ^{

                                                              NSLog(@"任务2执行");

                                                    });

    ④.监听任务1和任务二是否执行完: dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{

            NSLog(@"任务3执行");

        });

    打印结果为:任务1执行---------任务2执行----------任务3执行

    划重点:①dispatch_barrier_async(queue, ^{  })方法(我一般叫做栅栏或格栅),该方法的使用要求queue为自己创建的队列,不要使用全局队列和主队列,否则就失去使用栅栏(或者格栅)方法的意义;②dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{    })方法可以监听任务1和任务2是否完全执行完毕,只有前面的任务执行完毕之后才会执行任务3,任务3最常见的应用就是请求完数据,用于主线程的数据刷新或者继续进行其他操作;③dispatch_group_enter(group)方法和dispatch_group_leave(group)方法是成对使用的,该方法会被线程监听,可以比较安全的保证任务1和任务2妥妥的执行完毕之后再执行任务3。

    实现方式二:(信号量)

    ①.创建俩信号量: dispatch_semaphore_t sem1 = dispatch_semaphore_create(0);

                                  dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);

    ②.执行任务:

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

            dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER);

            NSLog(@"任务3");

        });

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);

            NSLog(@"任务2");

            dispatch_semaphore_signal(sem1);

        });

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            NSLog(@"任务1");

            dispatch_semaphore_signal(sem2);

        });

    打印结果为:任务1执行---------任务2执行----------任务3执行

    划重点:①dispatch_semaphore_t 创建的信号量sem1和sem2初始值给的都是0;                   ②第一个异步任务中dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER)方法会检查sem1的信号量值是否>0如果>0就会执行任务3,否者就会阻塞线程,任务3不会执行;           ③同理,第二个异步任务中dispatch_semaphore_wait(sem0, DISPATCH_TIME_FOREVER)方法会检查sem0的信号量值是否>0如果>0就会执行任务2,否者就会阻塞线程,任务2不会执行;                                                                                                                                        ④ 第三个异步任务中先执行任务1,然后dispatch_semaphore_signal(sem2)方法会给sem2信号量+1,sem2信号量+1后,第二个异步任务接收到信号,就会开始执行任务2,然后再执行 dispatch_semaphore_signal(sem1)给sem1增加信号量,同时,sem2的信号量会自动-1,变成0,后续如果不再给sem2增加信号量,就会一直阻塞下去,不再继续执行;                             ⑤sem1信号量+1后,第一个异步任务接收到信号,就会开始执行任务3,同时,sem1的信号量会自动-1,变成0,后续如果不再给sem2增加信号量,就会一直阻塞下去,不再继续执行 。

    相关文章

      网友评论

          本文标题:浅谈GCD的线程依赖

          本文链接:https://www.haomeiwen.com/subject/zgpihftx.html