浅谈GCD的线程依赖

2018-04-09  本文已影响0人  尼克Nick

之前对线程使用的不是太多,今天专门抽时间看了下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增加信号量,就会一直阻塞下去,不再继续执行 。

上一篇下一篇

猜你喜欢

热点阅读