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