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