• 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) 组合在执行同步任务时正常,在执行异步任务时正常。

  • 相关阅读:
    log4j使用方法(一)——先跑起来再说
    umasuo—ubuntu G++的安装
    Linux使用SVN server的简单介绍
    BeanUtils中copyProperties方法的使用
    标准化安装_RHEL5.5(X64)_Oracle10gR2
    Learn How To Use Oracle Flashback
    Learn How To Use Oracle Audit
    idea导入本地的eclipse项目
    Docker 资源汇总
    Docker Dockerfile
  • 原文地址:https://www.cnblogs.com/zhou--fei/p/6747938.html
Copyright © 2020-2023  润新知