美文网首页
GCD-线程栅栏

GCD-线程栅栏

作者: 153037c65b0c | 来源:发表于2020-02-28 17:24 被阅读0次

GCD的线程栅栏分为同步栅栏(dispatch_barrier_sync)和异步栅栏(dispatch_barrier_async)
同步栅栏:
-同步栅栏中的任务会等之前添加到同一队列的任务都结束后开始按顺序执行。
-同步栅栏的任务会在主线程运行,会阻塞当前代码,等栅栏函数中的任务完成后才会接着执行之后的代码,相当于开启了一个同步任务。
异步栅栏:
-异步栅栏中的任务会等之前添加到同一队列的任务都结束后开始按顺序执行。
-异步栅栏中的任务不在主线程运行,不会阻塞异步栅栏之后主线程的代码。

1.同步栅栏

    dispatch_queue_t queue = dispatch_queue_create("barrierQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 3; i++) {
        dispatch_async(queue, ^{
            sleep(1);
            NSLog(@"栅栏前任务%d 线程%@", i, [NSThread currentThread]);
        });
    }
    NSLog(@"代码经过栅栏前");
    dispatch_barrier_sync(queue, ^{
        NSLog(@"栅栏任务1,线程%@", [NSThread currentThread]);
        sleep(1);
    });
    dispatch_barrier_sync(queue, ^{
        NSLog(@"栅栏任务2,线程%@", [NSThread currentThread]);
        sleep(1);
    });
    NSLog(@"代码通过栅栏");
    for (int i = 0; i < 3; i++) {
        dispatch_async(queue, ^{
            sleep(1);
            NSLog(@"栅栏后任务%d 线程%@", i, [NSThread currentThread]);
        });
    }

运行结果:

2020-02-28 17:07:42.011765+0800 Test[24412:1701334] 代码经过栅栏前
2020-02-28 17:07:42.011890+0800 Test[24412:1701446] 栅栏前任务开始2 线程<NSThread: 0x600000364c80>{number = 5, name = (null)}
2020-02-28 17:07:42.011891+0800 Test[24412:1701439] 栅栏前任务开始0 线程<NSThread: 0x600000364bc0>{number = 3, name = (null)}
2020-02-28 17:07:42.011919+0800 Test[24412:1701445] 栅栏前任务开始1 线程<NSThread: 0x600000364a80>{number = 4, name = (null)}
2020-02-28 17:07:43.014260+0800 Test[24412:1701446] 栅栏前任务结束2 线程<NSThread: 0x600000364c80>{number = 5, name = (null)}
2020-02-28 17:07:43.014260+0800 Test[24412:1701439] 栅栏前任务结束0 线程<NSThread: 0x600000364bc0>{number = 3, name = (null)}
2020-02-28 17:07:43.014301+0800 Test[24412:1701445] 栅栏前任务结束1 线程<NSThread: 0x600000364a80>{number = 4, name = (null)}
2020-02-28 17:07:43.014488+0800 Test[24412:1701334] 栅栏任务1,线程<NSThread: 0x6000003eafc0>{number = 1, name = main}
2020-02-28 17:07:44.014744+0800 Test[24412:1701334] 栅栏任务2,线程<NSThread: 0x6000003eafc0>{number = 1, name = main}
2020-02-28 17:07:45.016132+0800 Test[24412:1701334] 代码通过栅栏
2020-02-28 17:07:46.019509+0800 Test[24412:1701445] 栅栏后任务0 线程<NSThread: 0x600000364a80>{number = 4, name = (null)}
2020-02-28 17:07:46.019552+0800 Test[24412:1701446] 栅栏后任务1 线程<NSThread: 0x600000364c80>{number = 5, name = (null)}
2020-02-28 17:07:46.019567+0800 Test[24412:1701444] 栅栏后任务2 线程<NSThread: 0x600000365400>{number = 6, name = (null)}

观察结果可以看到,主线程的"代码通过栅栏"在栅栏任务结束后才打印,并且栅栏任务所在的线程是主线程,所以同步栅栏会阻塞主线程,同步之后的代码要等到同步栅栏的任务完成后才会去执行。
观察栅栏任务0,1,2和同步栅栏任务1,2可以得出,同步栅栏中的任务要等栅栏前添加到同一队列的任务完成,才会按顺序执行。

2.异步栅栏

    dispatch_queue_t queue = dispatch_queue_create("barrierAsyncQueue", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 3; i++) {
        dispatch_async(queue, ^{
            NSLog(@"栅栏前任务开始%d 线程%@", i, [NSThread currentThread]);
            sleep(1);
            NSLog(@"栅栏前任务结束%d 线程%@", i, [NSThread currentThread]);
        });
    }
    NSLog(@"代码经过栅栏前");
    dispatch_barrier_async(queue, ^{
        NSLog(@"栅栏任务1,线程%@", [NSThread currentThread]);
        sleep(1);
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"栅栏任务2,线程%@", [NSThread currentThread]);
        sleep(1);
    });
    NSLog(@"代码通过栅栏");
    for (int i = 0; i < 3; i++) {
        dispatch_async(queue, ^{
            NSLog(@"栅栏后任务开始%d 线程%@", i, [NSThread currentThread]);
            sleep(1);
            NSLog(@"栅栏后任务结束%d 线程%@", i, [NSThread currentThread]);
        });
    }

运行结果:

2020-02-28 17:22:31.951608+0800 Test[24630:1724365] 代码经过栅栏前
2020-02-28 17:22:31.951707+0800 Test[24630:1724600] 栅栏前任务开始1 线程<NSThread: 0x600002cde540>{number = 4, name = (null)}
2020-02-28 17:22:31.951745+0800 Test[24630:1724816] 栅栏前任务开始2 线程<NSThread: 0x600002cde600>{number = 5, name = (null)}
2020-02-28 17:22:31.951779+0800 Test[24630:1724590] 栅栏前任务开始0 线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}
2020-02-28 17:22:31.951923+0800 Test[24630:1724365] 代码通过栅栏
2020-02-28 17:22:32.953949+0800 Test[24630:1724600] 栅栏前任务结束1 线程<NSThread: 0x600002cde540>{number = 4, name = (null)}
2020-02-28 17:22:32.953997+0800 Test[24630:1724816] 栅栏前任务结束2 线程<NSThread: 0x600002cde600>{number = 5, name = (null)}
2020-02-28 17:22:32.954026+0800 Test[24630:1724590] 栅栏前任务结束0 线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}
2020-02-28 17:22:32.954666+0800 Test[24630:1724590] 栅栏任务1开始,线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}
2020-02-28 17:22:33.955252+0800 Test[24630:1724590] 栅栏任务1结束,线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}
2020-02-28 17:22:33.955545+0800 Test[24630:1724590] 栅栏任务2开始,线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}
2020-02-28 17:22:34.956239+0800 Test[24630:1724590] 栅栏任务2结束,线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}
2020-02-28 17:22:35.960067+0800 Test[24630:1724816] 栅栏后任务1 线程<NSThread: 0x600002cde600>{number = 5, name = (null)}
2020-02-28 17:22:35.960067+0800 Test[24630:1724600] 栅栏后任务2 线程<NSThread: 0x600002cde540>{number = 4, name = (null)}
2020-02-28 17:22:35.960067+0800 Test[24630:1724590] 栅栏后任务0 线程<NSThread: 0x600002c3aa40>{number = 3, name = (null)}

观察结果可以看到,主线程的"代码通过栅栏"在栅栏任务开始前就打印,并且异步栅栏任务在子线程执行,所以异步栅栏任务不会阻塞栅栏后面主线程的代码。
观察栅栏任务0,1,2和异步栅栏任务1,2可以得出,异步栅栏中的任务要等栅栏前添加到同一队列的任务完成,才会按顺序执行。

相关文章

  • GCD-线程栅栏

    GCD的线程栅栏分为同步栅栏(dispatch_barrier_sync)和异步栅栏(dispatch_barri...

  • 7.3 多线程-GCD

    多线程-GCD 多线程-GCD-串行并行 多线程-GCD.png GCD-线程的通讯、延时操作、定时器 GCD-线...

  • iOS 多线程GCD-栅栏函数 dispatch_barrier

    GCD中有两个用来执行任务的常用函数用同步方法执行任务,其中 queue 是队列,block 是任务dispatc...

  • 06 GCD 并发队列

    03 GCD-并发队列 并发队列,异步执行 问题:1.会开几条线程?会开多条线程,线程数量是由GCD来决定2.会顺...

  • GCD-栅栏函数 dispatch_barrier_async

    dispatch_group 和 dispatch_barrier 的区别?案例1:如果有A、B、C 三个任务,需...

  • 闭锁和栅栏

    闭锁:可以延迟线程的进度直到线程到达某个终点状态,只有当某个条件满足的时候,所有线程才可能被并发执行。 栅栏:栅栏...

  • 同步工具类之CyclicBarrier

    一, CyclicBarrier栅栏简介 栅栏(Barrier)类似闭锁,他能阻塞一组线程直到某个事件发生.栅栏与...

  • 同步工具类CyclicBarrier原理及使用

    简介 栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置...

  • java并发编程实战栅栏

    栅栏类似于闭锁,它能阻塞一组线程直到某个事件发生。栅栏与闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续...

  • Java并发编程之CyclicBarrier详解

    简介栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,...

网友评论

      本文标题:GCD-线程栅栏

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