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

    在使用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);             

                }

            });

        });

        

        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)

        dispatch_group_notify(group1, queue1, ^{

            NSLog(@"Method1-全部任务执行完成");

        });

    同步任务运行结果:

    2018-08-22 16:48:51.092682+0800 test[47823:1537753] 任务2-同步任务执行-:0  第1s

    2018-08-22 16:48:51.092682+0800 test[47823:1537754] 任务1-同步任务执行-:0  第1s

    2018-08-22 16:48:52.093600+0800 test[47823:1537753] 任务2-同步任务执行-:1  第2s

    2018-08-22 16:48:52.098001+0800 test[47823:1537754] 任务1-同步任务执行-:1  第2s

    2018-08-22 16:48:53.097875+0800 test[47823:1537753] 任务2-同步任务执行-:2  第3s

    2018-08-22 16:48:53.098358+0800 test[47823:1537754] 任务1-同步任务执行-:2  第3s

    2018-08-22 16:48:53.098543+0800 test[47823:1537754] Method1-全部任务执行完成

     

    注意:后面肯定是

    先2个0,(前面的任务1,任务2顺序不定)

    再2个1,(前面的任务1,任务2顺序不定)

    再2个2,(前面的任务1,任务2顺序不定)

     

    如果任务2中的sleep改为休眠2s,结果为

     

     

    2018-12-07 10:25:57.475467+0800 GCDDemo[5322:12936911] 任务1-同步任务执行-:0  第1s

     

    2018-12-07 10:25:58.473856+0800 GCDDemo[5322:12936912] 任务2-同步任务执行-:0  第2s

     

    2018-12-07 10:25:58.477938+0800 GCDDemo[5322:12936911] 任务1-同步任务执行-:1  第2s

     

    2018-12-07 10:25:59.481760+0800 GCDDemo[5322:12936911] 任务1-同步任务执行-:2  第3s

     

    2018-12-07 10:26:00.474908+0800 GCDDemo[5322:12936912] 任务2-同步任务执行-:1  第4s

     

    2018-12-07 10:26:02.479513+0800 GCDDemo[5322:12936912] 任务2-同步任务执行-:2  第6s

     

    2018-12-07 10:26:02.479948+0800 GCDDemo[5322:12936912] 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);              

                }

            });

        });

        

        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)

        dispatch_group_notify(group1, queue1, ^{

            NSLog(@"Method1-全部任务执行完成");

        });

    异步任务运行结果:

    2018-08-22 16:52:58.636330+0800 test[47898:1541539] Method1-全部任务执行完成

    2018-08-22 16:52:59.636778+0800 test[47898:1541540] 任务1-异步任务执行-:0  第1s

    2018-08-22 16:52:59.636778+0800 test[47898:1541542] 任务2-异步任务执行-:0  第1s

    2018-08-22 16:53:00.637198+0800 test[47898:1541540] 任务1-异步任务执行-:1  第2s

    2018-08-22 16:53:00.637198+0800 test[47898:1541542] 任务2-异步任务执行-:1  第2s

    2018-08-22 16:53:01.642027+0800 test[47898:1541542] 任务2-异步任务执行-:2  第3s

    2018-08-22 16:53:01.641966+0800 test[47898:1541540] 任务1-异步任务执行-:2  第3s

     

    注意:后面肯定是

    先2个0,(前面的任务1,任务2顺序不定)

    再2个1,(前面的任务1,任务2顺序不定)

    再2个2,(前面的任务1,任务2顺序不定)

     

    如果任务2中的sleep改为休眠2s,结果为

    2018-12-07 10:36:55.875157+0800 GCDDemo[5494:12942841] Method1-全部任务执行完成

    2018-12-07 10:36:56.879707+0800 GCDDemo[5494:12942839] 任务1-异步任务执行-:0  第1s

    2018-12-07 10:36:57.876052+0800 GCDDemo[5494:12942838] 任务2-异步任务执行-:0  第2s

    2018-12-07 10:36:57.881002+0800 GCDDemo[5494:12942839] 任务1-异步任务执行-:1  第2s

    2018-12-07 10:36:58.884062+0800 GCDDemo[5494:12942839] 任务1-异步任务执行-:2  第3s

    2018-12-07 10:36:59.879717+0800 GCDDemo[5494:12942838] 任务2-异步任务执行-:1  第4s

    2018-12-07 10:37:01.883606+0800 GCDDemo[5494:12942838] 任务2-异步任务执行-:2  第6s

     

     

    Method1-全部任务执行完成 这句会最先打印,是因为不用等dispatch_async的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);

        });

        

        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)

        dispatch_group_notify(group2, queue2, ^{

            NSLog(@"Method2-全部任务执行完成");

        });

    同步任务运行结果:

    2018-08-22 16:54:22.052754+0800 test[47922:1542807] 任务1-同步任务执行-:0  第1s

    2018-08-22 16:54:23.054257+0800 test[47922:1542807] 任务1-同步任务执行-:1  第2s

    2018-08-22 16:54:24.055846+0800 test[47922:1542807] 任务1-同步任务执行-:2  第3s

    2018-08-22 16:54:25.057378+0800 test[47922:1542807] 任务2-同步任务执行-:0  第4s

    2018-08-22 16:54:26.058930+0800 test[47922:1542807] 任务2-同步任务执行-:1  第5s

    2018-08-22 16:54:27.059586+0800 test[47922:1542807] 任务2-同步任务执行-:2  第6s

    2018-08-22 16:54:27.060009+0800 test[47922:1542842] 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);

        });

        

        //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)

        dispatch_group_notify(group2, queue2, ^{

            NSLog(@"Method2-全部任务执行完成");

        });

    异步任务运行结果:

    2018-08-22 16:55:46.484704+0800 test[47956:1544221] 任务2-异步任务执行-:0  第1s

    2018-08-22 16:55:46.484703+0800 test[47956:1544220] 任务1-异步任务执行-:0  第1s

    2018-08-22 16:55:47.489386+0800 test[47956:1544220] 任务1-异步任务执行-:1  第2s

    2018-08-22 16:55:47.489386+0800 test[47956:1544221] 任务2-异步任务执行-:1  第2s

    2018-08-22 16:55:48.491734+0800 test[47956:1544220] 任务1-异步任务执行-:2  第3s

    2018-08-22 16:55:48.491749+0800 test[47956:1544221] 任务2-异步任务执行-:2  第3s

    2018-08-22 16:55:48.492144+0800 test[47956:1544221] Method2-全部任务执行完成

     

     

    信号量控制并发数

    创建一个信号量,设置最大并发数为5,5个线程,异步执行

     

        dispatch_semaphore_t sema = dispatch_semaphore_create(5);

        for (int i = 0; i<100; i++) {

            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

                sleep(3);

                printf("%d ",i);

                dispatch_semaphore_signal(sema);

            });

        }

     

    打印结果为:(可发现每5个一组,顺序不定)

    0

    1

    2

    3

    4

    6

    5

    7

    8

    9

    11

    10

    13

    12

    14

    15

    16

    17

    18

    19

    20

    22

    23

    21

    24

    25

    29

    27

    28

    26

    30

    32

    31

    33

    34

    35

    36

    38

    37

    39

    41

    42

    43

    40

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    57

    56

    58

    59

    60

    62

    61

    63

    64

    65

    67

    66

    68

    69

    70

    74

    72

    71

    73

    75

    77

    76

    78

    79

    80

    81

    83

    82

    84

    85

    87

    86

    88

    89

    91

    90

    92

    94

    93

    95

    97

    96

    98

    99

     

     

     

  • 相关阅读:
    LostRoutes项目日志——玩家飞机精灵Fighter解析
    quartz Cron表达式一分钟教程
    vue-cli入门
    SQL中merge into用法
    SQLSERVER查询那个表里有数据
    C#实现复杂XML的序列化与反序列化
    MVC和WebApi 使用get和post 传递参数。
    项目管理软件推荐
    JS跨域请求
    Android动画效果translate、scale、alpha、rotate详解
  • 原文地址:https://www.cnblogs.com/huangzs/p/9518810.html
Copyright © 2011-2022 走看看