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\n",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

 

 

 

转载于:https://www.cnblogs.com/huangzs/p/9518810.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值