GCD栅栏函数dispatch_barrier_async

作者: Ocean_e553 | 来源:发表于2020-08-21 16:07 被阅读0次

在项目中有很多场景需要控制任务的执行顺序

  1. 需要等任务A, 任务B, 任务C都完成后(其中A, B, C没有顺序要求), 才进行下一步的处理任务, 可以使用 dispatch_group很方便的完成 (也可以使用栅栏函数)
  2. 如果上面的A, B, C任务顺序也有顺序要求呢? 必须A任务完成后, 才能进行B任务, B完成后才进行C任务, 这时我们就需要用到栅栏函数

第一种情况
A, B, C任务完成之后(A, B, C无顺序要求), 进行任务D
1.使用dispatch_barrier

dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{
    NSLog(@"开始任务A");
    [NSThread sleepForTimeInterval:1];
    NSLog(@"任务A done.");
});
dispatch_async(queue, ^{
    NSLog(@"开始任务B");
    [NSThread sleepForTimeInterval:0.5];
    NSLog(@"任务B done.");
});
dispatch_async(queue, ^{
    NSLog(@"开始任务C");
    [NSThread sleepForTimeInterval:0.2];
    NSLog(@"任务C done.");
});

dispatch_barrier_async(queue, ^{
    NSLog(@"----------> barrier <----------");
});

dispatch_async(queue, ^{
    NSLog(@"开始任务D");
});

输出如下:

2020-08-21 15:51:09.404645+0800 TestDemo[18135:4901422] 开始任务A
2020-08-21 15:51:09.404748+0800 TestDemo[18135:4901424] 开始任务B
2020-08-21 15:51:09.404792+0800 TestDemo[18135:4901423] 开始任务C
2020-08-21 15:51:09.609983+0800 TestDemo[18135:4901423] 任务C done.
2020-08-21 15:51:09.909982+0800 TestDemo[18135:4901424] 任务B done.
2020-08-21 15:51:10.409928+0800 TestDemo[18135:4901422] 任务A done.
2020-08-21 15:51:10.410539+0800 TestDemo[18135:4901422] ----------> barrier <----------
2020-08-21 15:51:10.410845+0800 TestDemo[18135:4901422] 开始任务D

如果不加barrier 函数, 输出如下:

2020-08-21 15:53:48.844822+0800 TestDemo[18138:4902485] 开始任务A
2020-08-21 15:53:48.844973+0800 TestDemo[18138:4902486] 开始任务B
2020-08-21 15:53:48.845054+0800 TestDemo[18138:4902484] 开始任务D
2020-08-21 15:53:48.845052+0800 TestDemo[18138:4902480] 开始任务C
2020-08-21 15:53:49.050337+0800 TestDemo[18138:4902480] 任务C done.
2020-08-21 15:53:49.350229+0800 TestDemo[18138:4902486] 任务B done.
2020-08-21 15:53:49.850151+0800 TestDemo[18138:4902485] 任务A done.

2.使用 dispatch_group

dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_t group = dispatch_group_create();

dispatch_group_enter(group);
dispatch_async(queue, ^{
    NSLog(@"开始任务A");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"任务A done.");
    dispatch_group_leave(group);
});

dispatch_group_enter(group);
dispatch_async(queue, ^{
    NSLog(@"开始任务B");
    [NSThread sleepForTimeInterval:2];
    NSLog(@"任务B done.");
    dispatch_group_leave(group);
});

dispatch_group_enter(group);
dispatch_async(queue, ^{
    NSLog(@"开始任务C");
    [NSThread sleepForTimeInterval:1];
    NSLog(@"任务C done.");
    dispatch_group_leave(group);
});

dispatch_group_notify(group, queue, ^{
    NSLog(@"开始任务D");
});

输出如下:

2020-08-21 16:03:22.023610+0800 TestDemo[18152:4906177] 开始任务A
2020-08-21 16:03:22.023724+0800 TestDemo[18152:4906173] 开始任务B
2020-08-21 16:03:22.023750+0800 TestDemo[18152:4906178] 开始任务C
2020-08-21 16:03:23.028869+0800 TestDemo[18152:4906178] 任务C done.
2020-08-21 16:03:24.028923+0800 TestDemo[18152:4906173] 任务B done.
2020-08-21 16:03:25.028788+0800 TestDemo[18152:4906177] 任务A done.
2020-08-21 16:03:25.029077+0800 TestDemo[18152:4906177] 开始任务D

第二种情况
A, B, C任务完成之后(A, B, C顺序要求依次执行), 进行任务D

dispatch_queue_t queue = dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_barrier_async(queue, ^{
    NSLog(@"开始任务A");
    [NSThread sleepForTimeInterval:1];
    NSLog(@"任务A done.");
});
dispatch_barrier_async(queue, ^{
    NSLog(@"开始任务B");
    [NSThread sleepForTimeInterval:0.5];
    NSLog(@"任务B done.");
});
dispatch_barrier_async(queue, ^{
    NSLog(@"开始任务C");
    [NSThread sleepForTimeInterval:0.2];
    NSLog(@"任务C done.");
});

dispatch_barrier_async(queue, ^{
    NSLog(@"开始任务D");
});

输出如下:

2020-08-21 15:57:08.494651+0800 TestDemo[18142:4903586] 开始任务A
2020-08-21 15:57:09.499985+0800 TestDemo[18142:4903586] 任务A done.
2020-08-21 15:57:09.500460+0800 TestDemo[18142:4903586] 开始任务B
2020-08-21 15:57:10.005840+0800 TestDemo[18142:4903586] 任务B done.
2020-08-21 15:57:10.006092+0800 TestDemo[18142:4903586] 开始任务C
2020-08-21 15:57:10.211303+0800 TestDemo[18142:4903586] 任务C done.
2020-08-21 15:57:10.211750+0800 TestDemo[18142:4903586] 开始任务D

相关文章

网友评论

    本文标题:GCD栅栏函数dispatch_barrier_async

    本文链接:https://www.haomeiwen.com/subject/knoujktx.html