美文网首页
dispatch_barrier_async、dispatch_

dispatch_barrier_async、dispatch_

作者: Triumphant | 来源:发表于2022-02-28 10:28 被阅读0次

    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

    相关文章

      网友评论

          本文标题:dispatch_barrier_async、dispatch_

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