zoukankan      html  css  js  c++  java
  • dispatch_group_t 日常使用注意事项

    一、背景简介
    平时在进行多线程处理任务时,有时候希望多个任务之间存在着一种联系,希望在所有的任务执行完后做一些总结性处理。
    那么就可以将多个任务放在一个任务组中进行统一管理。dispatch提供了相应的API供我们完成这一需求。

    二、dispatch_group_t相关属性介绍
    1.dispatch_group_async(group, queue, block);
    将block任务添加到queue队列,并被group组管理
    2.dispatch_group_enter(group);
    声明dispatch_group_enter(group)下面的任务由group组管理,group组的任务数+1
    3.dispatch_group_leave(group);
    相应的任务执行完成,group组的任务数-1
    4.dispatch_group_create();
    创建一个group组
    5.dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
    当前线程暂停,等待dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)上面的任务执行完成后,线程才继续执行。
    6.dispatch_group_notify(group1, queue1,block);
    监听group组中任务的完成状态,当所有的任务都执行完成后,触发block块,执行总结性处理。

    三、常见用法的区别
    在使用group组处理任务时,常见的有两种组合。
    其一:

    dispatch_group_async(group, queue, block);

    dispatch_group_notify(group1, queue1, block);

    在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

    第一种:同步任务时

      dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group1 = dispatch_group_create();
        
        dispatch_group_async(group1, queue1, ^{
            dispatch_sync(queue1, ^{
                for (NSInteger i =0; i<3; i++) {
                    sleep(1);
                    NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);
    
                }
            });
        });
        
        
        dispatch_group_async(group1, queue1, ^{
            dispatch_sync(queue1, ^{
                for (NSInteger i =0; i<3; i++) {
                    sleep(1);
                    NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
                    
                }
            });
        });
        
    //    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
    //    dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
        
        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
        dispatch_group_notify(group1, queue1, ^{
            NSLog(@"Method1-全部任务执行完成");
        });

    同步任务运行结果:

    2017-04-22 14:28:05.883 MyTestWorkProduct[27793:158785] 任务1-同步任务执行-:0
    2017-04-22 14:28:05.884 MyTestWorkProduct[27793:159210] 任务1-同步任务执行-:0
    2017-04-22 14:28:06.885 MyTestWorkProduct[27793:159210] 任务1-同步任务执行-:1
    2017-04-22 14:28:06.885 MyTestWorkProduct[27793:158785] 任务1-同步任务执行-:1
    2017-04-22 14:28:07.886 MyTestWorkProduct[27793:158785] 任务1-同步任务执行-:2
    2017-04-22 14:28:07.886 MyTestWorkProduct[27793:159210] 任务1-同步任务执行-:2
    2017-04-22 14:28:07.886 MyTestWorkProduct[27793:159186] Method1-全部任务执行完成

    第二种:异步任务时

     dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group1 = dispatch_group_create();
        
        dispatch_group_async(group1, queue1, ^{
            dispatch_async(queue1, ^{
                for (NSInteger i =0; i<3; i++) {
                    sleep(1);
                    NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);
    
                }
            });
        });
        
        
        dispatch_group_async(group1, queue1, ^{
            dispatch_async(queue1, ^{
                for (NSInteger i =0; i<3; i++) {
                    sleep(1);
                    NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
                    
                }
            });
        });
        
    //    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
    //    dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
        
        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
        dispatch_group_notify(group1, queue1, ^{
            NSLog(@"Method1-全部任务执行完成");
        });

    异步任务运行结果:

    2017-04-22 14:12:28.889 MyTestWorkProduct[27424:147249] Method1-全部任务执行完成
    2017-04-22 14:12:29.893 MyTestWorkProduct[27424:147231] 任务2-异步任务执行-:0
    2017-04-22 14:12:29.893 MyTestWorkProduct[27424:146850] 任务1-异步任务执行-:0
    2017-04-22 14:12:30.896 MyTestWorkProduct[27424:147231] 任务2-异步任务执行-:1
    2017-04-22 14:12:30.896 MyTestWorkProduct[27424:146850] 任务1-异步任务执行-:1
    2017-04-22 14:12:31.901 MyTestWorkProduct[27424:147231] 任务2-异步任务执行-:2
    2017-04-22 14:12:31.901 MyTestWorkProduct[27424:146850] 任务1-异步任务执行-:2

    结论:dispatch_group_async(group, queue, block) 和 dispatch_group_notify(group1, queue1, block) 组合在执行同步任务时正常,在执行异步任务时不正常。

    其二

    dispatch_group_enter(group);

    dispatch_group_leave(group);

     dispatch_group_notify(group1, queue1,block);

    在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

    第一种:同步任务时

     dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group2 = dispatch_group_create();
        
    
        dispatch_group_enter(group2);
        dispatch_sync(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    
        
        dispatch_group_enter(group2);
        dispatch_sync(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    //    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
    //    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
        
        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
        dispatch_group_notify(group2, queue2, ^{
            NSLog(@"Method2-全部任务执行完成");
        });

    同步任务执行结果:

    2017-04-22 14:28:05.884 MyTestWorkProduct[27793:159186] 任务2-同步任务执行-:0
    2017-04-22 14:28:06.885 MyTestWorkProduct[27793:159186] 任务2-同步任务执行-:1
    2017-04-22 14:28:07.886 MyTestWorkProduct[27793:159186] 任务2-同步任务执行-:2
    2017-04-22 14:28:08.887 MyTestWorkProduct[27793:158785] 任务2-同步任务执行-:0
    2017-04-22 14:28:09.888 MyTestWorkProduct[27793:158785] 任务2-同步任务执行-:1
    2017-04-22 14:28:10.889 MyTestWorkProduct[27793:158785] 任务2-同步任务执行-:2
    2017-04-22 14:28:10.889 MyTestWorkProduct[27793:159830] Method2-全部任务执行完成

    第二种:异步任务时

       dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group2 = dispatch_group_create();
        
    
        dispatch_group_enter(group2);
        dispatch_async(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    
        
        dispatch_group_enter(group2);
        dispatch_async(queue2, ^{
            for (NSInteger i =0; i<3; i++) {
                sleep(1);
                NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i);
                
            }
            dispatch_group_leave(group2);
        });
        
    //    //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
    //    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
        
        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
        dispatch_group_notify(group2, queue2, ^{
            NSLog(@"Method2-全部任务执行完成");
        });

    异步任务执行结果:

    2017-04-22 14:16:38.705 MyTestWorkProduct[27518:149631] 任务1-异步任务执行-:0
    2017-04-22 14:16:38.705 MyTestWorkProduct[27518:149624] 任务2-异步任务执行-:0
    2017-04-22 14:16:39.709 MyTestWorkProduct[27518:149631] 任务1-异步任务执行-:1
    2017-04-22 14:16:39.709 MyTestWorkProduct[27518:149624] 任务2-异步任务执行-:1
    2017-04-22 14:16:40.712 MyTestWorkProduct[27518:149624] 任务2-异步任务执行-:2
    2017-04-22 14:16:40.712 MyTestWorkProduct[27518:149631] 任务1-异步任务执行-:2
    2017-04-22 14:16:40.713 MyTestWorkProduct[27518:149631] Method2-全部任务执行完成

    结论:

    dispatch_group_enter(group)、dispatch_group_leave(group) 和  dispatch_group_notify(group1, queue1,block) 组合在执行同步任务时正常,在执行异步任务时正常。

  • 相关阅读:
    mysqlp批量替换的sql语句
    Paypal 支付功能的 C# .NET / JS 实现
    Layui table 组件的使用:初始化加载数据、数据刷新表格、传参数
    WinForm DataGridView 绑定泛型List(List<T>)/ArrayList不显示的原因和解决
    entity framework codefirst 用户代码未处理DataException,InnerException基础提供程序在open上失败,数据库生成失败
    《设计模式》一书中的23种设计模式
    C++程序实例唯一方案,窗口只打开一次,程序只打开一次
    重构——与设计模式的恋情
    重构——一个小例子
    C#通过调用WinApi打印PDF文档类,服务器PDF打印、IIS PDF打印
  • 原文地址:https://www.cnblogs.com/zhou--fei/p/6747938.html
Copyright © 2011-2022 走看看