dispatch_barrier_async、dispatch_

2022-02-28  本文已影响0人  Triumphant

https://blog.csdn.net/Lu_Ca/article/details/80691965

1、dispatch_barrier_async

dispatch_barrier_async用于等待前面的任务执行完毕后自己才执行,而它后面的任务需等待它完成之后才执行。一个典型的例子就是数据的读写,通常为了防止文件读写导致冲突,我们会创建一个串行的队列,所有的文件操作都是通过这个队列来执行,比如FMDB,这样就可以避免读写冲突。不过其实这样效率是有提升的空间的,当没有更新数据时,读操作其实是可以并行进行的,而写操作需要串行的执行,如何实现呢:

dispatch_queue_t queue = dispatch_queue_create("Database_Queue", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{

        NSLog(@"reading data1");

    });

    dispatch_async(queue, ^{

        NSLog(@"reading data2");

    });

    dispatch_barrier_async(queue, ^{

        NSLog(@"writing data1");

        [NSThread sleepForTimeInterval:1];

    });

    dispatch_async(queue, ^{

        [NSThread sleepForTimeInterval:1];

        NSLog(@"reading data3");

    });

执行结果如下:

GCDTests[13360:584316] reading data2

GCDTests[13360:584317] reading data1

GCDTests[13360:584317] writing data1

GCDTests[13360:584317] reading data3

我们将写数据的操作放在dispatch_barrier_async中,这样能确保在写数据的时候会等待前面的读操作完成,而后续的读操作也会等到写操作完成后才能继续执行,提高文件读写的执行效率。

2、dispatch_apply

dispatch_apply类似一个for循环,会在指定的dispatch queue中运行block任务n次,如果队列是并发队列,则会并发执行block任务,dispatch_apply是一个同步调用,block任务执行n次后才返回。

简单的使用方法:

dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);

//并发的运行一个block任务5次

dispatch_apply(5, queue, ^(size_t i) {

    NSLog(@"do a job %zu times",i+1);

});

NSLog(@"go on");

输出结果:

GCDTests[10029:760640] do a job 2 times

GCDTests[10029:760640] do a job 1 times

GCDTests[10029:760640] do a job 3 times

GCDTests[10029:760640] do a job 5 times

GCDTests[10029:760640] do a job 4 times

GCDTests[10029:760640] go on

3、dispatch_block_notify

dispatch_block_notify当观察的某个block执行结束之后立刻通知提交另一特定的block到指定的queue中执行,该函数有三个参数,第一参数是需要观察的block,第二个参数是被通知block提交执行的queue,第三参数是当需要被通知执行的block,函数的原型:

void dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue,

        dispatch_block_t notification_block);

具体使用的方法:

    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);

    dispatch_block_t previousBlock = dispatch_block_create(0, ^{

        NSLog(@"previousBlock begin");

        [NSThread sleepForTimeInterval:1];

        NSLog(@"previousBlock done");

    });

    dispatch_async(queue, previousBlock);

    dispatch_block_t notifyBlock = dispatch_block_create(0, ^{

        NSLog(@"notifyBlock");

    });

    //当previousBlock执行完毕后,提交notifyBlock到global queue中执行

    dispatch_block_notify(previousBlock, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), notifyBlock);

运行结果:

GCDTests[17129:895673] previousBlock begin

GCDTests[17129:895673] previousBlock done

GCDTests[17129:895673] notifyBlock

4、dispatch_group_wait

dispatch_group_wait会同步地等待group中所有的block执行完毕后才继续执行,类似于dispatch barrier

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_t group = dispatch_group_create();

//将任务异步地添加到group中去执行

dispatch_group_async(group,queue,^{ NSLog(@"block1"); });

dispatch_group_async(group,queue,^{ NSLog(@"block2"); });

dispatch_group_wait(group,DISPATCH_TIME_FOREVER);

NSLog(@"go on");

执行结果如下,只有block1跟block2执行完毕后才会执行dispatch_group_wait后面的内容。

GCDTests[954:41031] block2

GCDTests[954:41032] block1

GCDTests[954:40847] go on

5、dispatch_group_notify

功能与dispatch_group_wait类似,不过该过程是异步的,不会阻塞该线程,dispatch_group_notify有三个参数

void dispatch_group_notify(dispatch_group_t group, //要观察的group

                          dispatch_queue_t queue,  //block执行的队列

                          dispatch_block_t block);  //当group中所有任务执行完毕之后要执行的block

简单的示意用法:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,queue,^{ NSLog(@"block1"); });

dispatch_group_async(group,queue,^{ NSLog(@"block2"); });

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    NSLog(@"done");

});

NSLog(@"go on");

可以看到如下的执行结果

GCDTests[1046:45104] go on

GCDTests[1046:45153] block1

GCDTests[1046:45152] block2

GCDTests[1046:45104] done

上一篇下一篇

猜你喜欢

热点阅读