美文网首页
GCD dispatch_barrier_async和dispa

GCD dispatch_barrier_async和dispa

作者: Cwwng | 来源:发表于2020-11-06 21:06 被阅读0次

1、栅栏函数使用场景

异步执行两组操作,且第一组操作(多个任务)执行完成后,才开始执行第二组操作(多个任务)。

2、代码

    dispatch_queue_t queueConcurrent = dispatch_queue_create("com.concurrent", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"currentThread - %@",[NSThread currentThread]);  // 打印当前线程
    // 异步任务
    dispatch_async(queueConcurrent, ^{
        sleep(4);
        NSLog(@"1 - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(3);
        NSLog(@"2 - %@",[NSThread currentThread]);
    });
    //栅栏函数
    dispatch_barrier_async(queueConcurrent, ^{
        sleep(2);
        NSLog(@"barrier - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(2);
        NSLog(@"3 - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(1);
        NSLog(@"4 - %@",[NSThread currentThread]);
    });
2020-11-06 20:51:10.092033+0800 Demo[30480:2211900] currentThread - <NSThread: 0x600002150500>{number = 1, name = main}
2020-11-06 20:51:13.097126+0800 Demo[30480:2212114] 2 - <NSThread: 0x60000216ce00>{number = 6, name = (null)}
2020-11-06 20:51:14.095570+0800 Demo[30480:2212115] 1 - <NSThread: 0x600002167400>{number = 4, name = (null)}
2020-11-06 20:51:16.098314+0800 Demo[30480:2212115] barrier - <NSThread: 0x600002167400>{number = 4, name = (null)}
2020-11-06 20:51:17.102508+0800 Demo[30480:2212114] 4 - <NSThread: 0x60000216ce00>{number = 6, name = (null)}
2020-11-06 20:51:18.103299+0800 Demo[30480:2212115] 3 - <NSThread: 0x600002167400>{number = 4, name = (null)}

3、dispatch_barrier_async和dispatch_barrier_sync区别

官方文档
dispatch_barrier_sync: Submits a barrier block object for execution and waits until that block completes.(提交一个栅栏函数在执行中,它会等待栅栏函数执行完)
dispatch_barrier_async: Submits a barrier block for asynchronous execution and returns immediately.(提交一个栅栏函数在异步执行中,它会立马返回)

直接代码对比

    dispatch_queue_t queueConcurrent = dispatch_queue_create("com.concurrent", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"currentThread - %@",[NSThread currentThread]);  // 打印当前线程
    // 异步任务
    dispatch_async(queueConcurrent, ^{
        sleep(4);
        NSLog(@"1 - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(3);
        NSLog(@"2 - %@",[NSThread currentThread]);
    });
    //栅栏函数
    dispatch_barrier_async(queueConcurrent, ^{
        sleep(2);
        NSLog(@"barrier - %@",[NSThread currentThread]);
    });
    NSLog(@"判断区别");
    dispatch_async(queueConcurrent, ^{
        sleep(2);
        NSLog(@"3 - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(1);
        NSLog(@"4 - %@",[NSThread currentThread]);
    });
2020-11-06 20:56:36.682431+0800 Demo[30728:2217328] currentThread - <NSThread: 0x600003944580>{number = 1, name = main}
2020-11-06 20:56:36.682687+0800 Demo[30728:2217328] 判断区别
2020-11-06 20:56:39.688071+0800 Demo[30728:2217409] 2 - <NSThread: 0x600003902540>{number = 5, name = (null)}
2020-11-06 20:56:40.686471+0800 Demo[30728:2217412] 1 - <NSThread: 0x600003909480>{number = 6, name = (null)}
2020-11-06 20:56:42.691081+0800 Demo[30728:2217412] barrier - <NSThread: 0x600003909480>{number = 6, name = (null)}
2020-11-06 20:56:43.693779+0800 Demo[30728:2217409] 4 - <NSThread: 0x600003902540>{number = 5, name = (null)}
2020-11-06 20:56:44.692659+0800 Demo[30728:2217412] 3 - <NSThread: 0x600003909480>{number = 6, name = (null)}
    dispatch_queue_t queueConcurrent = dispatch_queue_create("com.concurrent", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"currentThread - %@",[NSThread currentThread]);  // 打印当前线程
    // 异步任务
    dispatch_async(queueConcurrent, ^{
        sleep(4);
        NSLog(@"1 - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(3);
        NSLog(@"2 - %@",[NSThread currentThread]);
    });
    //栅栏函数
    dispatch_barrier_sync(queueConcurrent, ^{
        sleep(2);
        NSLog(@"barrier - %@",[NSThread currentThread]);
    });
    NSLog(@"判断区别");
    dispatch_async(queueConcurrent, ^{
        sleep(2);
        NSLog(@"3 - %@",[NSThread currentThread]);
    });
    dispatch_async(queueConcurrent, ^{
        sleep(1);
        NSLog(@"4 - %@",[NSThread currentThread]);
    });
2020-11-06 20:57:33.124990+0800 Demo[30788:2218815] currentThread - <NSThread: 0x6000019101c0>{number = 1, name = main}
2020-11-06 20:57:36.125472+0800 Demo[30788:2218907] 2 - <NSThread: 0x60000195d8c0>{number = 7, name = (null)}
2020-11-06 20:57:37.130359+0800 Demo[30788:2218908] 1 - <NSThread: 0x60000191e980>{number = 3, name = (null)}
2020-11-06 20:57:39.131764+0800 Demo[30788:2218815] barrier - <NSThread: 0x6000019101c0>{number = 1, name = main}
2020-11-06 20:57:39.132150+0800 Demo[30788:2218815] 判断区别
2020-11-06 20:57:40.133453+0800 Demo[30788:2218911] 4 - <NSThread: 0x60000192ce00>{number = 4, name = (null)}
2020-11-06 20:57:41.132689+0800 Demo[30788:2218908] 3 - <NSThread: 0x60000191e980>{number = 3, name = (null)}

理解:
dispatch_barrier_sync 阻塞当前线程,需要等待栅栏任务执行完,才会执行栅栏后面的任务。
dispatch_barrier_async 不阻塞当前线程,无需等待栅栏任务执行完,会继续往下走(任务保留在队列里)

原因:
同步栅栏时栅栏函数在主线程中执行。
异步栅栏中开辟子线程,栅栏函数在子线程中执行。

4、注意

官方文档
The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like the dispatch_sync function.
在使用栅栏函数时,使用自定义队列才有意义。如果用的是串行队列或者系统提供的全局并发队列,这个栅栏函数的作用等同于一个同步函数的作用。

所以,必须自己使用dispatch_queue_create创建并行队列。如果你使用了串行队列或者全局队列,dispatch_barrier_async相当于dispatch_async,而dispatch_barrier_sync相当于dispatch_sync。

全局并发队列栅栏函数失效原因:
全局并发队列是系统创建,源码是宏定义数组。会在全局并发队列中处理它自有任务。使用栅栏函数阻塞全局并发队列无效。

相关文章

网友评论

      本文标题:GCD dispatch_barrier_async和dispa

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