美文网首页iOS面试
iOS 多线程GCD-栅栏函数 dispatch_barrier

iOS 多线程GCD-栅栏函数 dispatch_barrier

作者: PPFSaber | 来源:发表于2018-03-27 18:31 被阅读733次
  • GCD中有两个用来执行任务的常用函数
    用同步方法执行任务,其中 queue 是队列,block 是任务
    dispatch_sync(dispatch_queue_t queue, dispatch_block_t blcok);

    用异步方法执行任务,其中 queue 是队列,block 是任务
    dispatch_async(dispatch_queue_t queue, dispatch_block_t blcok);

  • 同步和异步的区别
    同步:只能在当前线程中执行任务,不具备开启新线程的能力
    异步:可以在新线程中执行任务,具备开启新线程的能力。

  • GCD中还有两个用来执行任务的函数
    当我们的任务有依赖关系的时候,比如任务1和2执行完毕后才能执行任务3和4,这时候我们可以用到这个函数——栅栏函数。其中 queue 是队列,block 是任务。

    提交一个栅栏函数在执行中,它会等待栅栏函数执行完再去执行下一行代码(注意是下一行代码),同步栅栏函数是在主线程中执行的
    dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t blcok);

    提交一个栅栏函数在异步执行中,它会立马返回开始执行下一行代码(不用等待任务执行完毕)
    dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t blcok);

共同点

1、都会等待在它前面插入队列的任务(1、2、3)先执行完
2、都会等待他们自己的任务(barrier)执行完再执行后面的任务(4、5、6)(注意这里说的是任务不是下一行代码)

不同点

1、dispatch_barrier_sync需要等待自己的任务(barrier)结束之后,才会继续添加并执行写在barrier后面的任务(4、5、6),然后执行后面的任务
2、dispatch_barrier_async将自己的任务(barrier)插入到queue之后,不会等待自己的任务结束,它会继续把后面的任务(4、5、6)插入到queue,然后执行任务。
 
 //并发队列   栅栏函数
 - (void)concurrentQueueAsyncAndSync2BarrrierTest
 {
 
 dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
 
 dispatch_async(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"任务0 %d",i);
 }];
 });
 
 dispatch_async(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"任务1 %d",i);
 }];
 });
 
 
 NSLog(@"同步栅栏 start😊");
 dispatch_barrier_sync(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"同步栅栏, %@",[NSThread currentThread]);
 }];
 });
 NSLog(@"同步栅栏 end😊");
 
 
 dispatch_async(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"任务2 %d",i);
 }];
 });
 
 dispatch_async(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"任务3 %d",i);
 }];
 });
 
 NSLog(@"异步栅栏 start 😄");
 dispatch_barrier_async(concurrentQueue, ^{
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"异步栅栏 %@",[NSThread currentThread]);
 }];
 });
 
 NSLog(@"异步栅栏 end 😄");
 
 dispatch_async(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"任务4 %d",i);
 }];
 });
 
 
 
 dispatch_async(concurrentQueue, ^{
 
 [self forNumIncrementCondition:5 actionBlock:^(int i) {
 NSLog(@"任务5 %d",i);
 }];
 });
 
 }
 
 
 
 - (void)forNumIncrementCondition:(NSUInteger )num  actionBlock:(void(^)(int i))actionBlcok
 {
 for (int a = 0; a < num; a ++)
 {
 if (actionBlcok) {
 actionBlcok(a);
 }
 }
 }
 

答应结果如下

 PPFGCD_demo1[5141:1319243] 同步栅栏 start😊
 PPFGCD_demo1[5141:1319371] 任务0 0
 PPFGCD_demo1[5141:1322592] 任务1 0
 PPFGCD_demo1[5141:1319371] 任务0 1
 PPFGCD_demo1[5141:1322592] 任务1 1
 PPFGCD_demo1[5141:1319371] 任务0 2
 PPFGCD_demo1[5141:1322592] 任务1 2
 PPFGCD_demo1[5141:1319371] 任务0 3
 PPFGCD_demo1[5141:1322592] 任务1 3
 PPFGCD_demo1[5141:1319371] 任务0 4
 PPFGCD_demo1[5141:1322592] 任务1 4
 PPFGCD_demo1[5141:1319243] 同步栅栏, <NSThread: 0x60800006f300>{number = 1, name = main}
 PPFGCD_demo1[5141:1319243] 同步栅栏, <NSThread: 0x60800006f300>{number = 1, name = main}
 PPFGCD_demo1[5141:1319243] 同步栅栏, <NSThread: 0x60800006f300>{number = 1, name = main}
 PPFGCD_demo1[5141:1319243] 同步栅栏, <NSThread: 0x60800006f300>{number = 1, name = main}
 PPFGCD_demo1[5141:1319243] 同步栅栏, <NSThread: 0x60800006f300>{number = 1, name = main}
 PPFGCD_demo1[5141:1319243] 同步栅栏 end😊
 PPFGCD_demo1[5141:1319243] 异步栅栏 start 😄
 PPFGCD_demo1[5141:1319371] 任务3 0
 PPFGCD_demo1[5141:1322592] 任务2 0
 PPFGCD_demo1[5141:1319243] 异步栅栏 end 😄
 PPFGCD_demo1[5141:1319371] 任务3 1
 PPFGCD_demo1[5141:1322592] 任务2 1
 PPFGCD_demo1[5141:1319371] 任务3 2
 PPFGCD_demo1[5141:1322592] 任务2 2
 PPFGCD_demo1[5141:1319371] 任务3 3
 PPFGCD_demo1[5141:1322592] 任务2 3
 PPFGCD_demo1[5141:1319371] 任务3 4
 PPFGCD_demo1[5141:1322592] 任务2 4
 PPFGCD_demo1[5141:1322592] 异步栅栏 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
 PPFGCD_demo1[5141:1322592] 异步栅栏 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
 PPFGCD_demo1[5141:1322592] 异步栅栏 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
 PPFGCD_demo1[5141:1322592] 异步栅栏 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
 PPFGCD_demo1[5141:1322592] 异步栅栏 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
 PPFGCD_demo1[5141:1322592] 任务4 0
 PPFGCD_demo1[5141:1319371] 任务5 0
 PPFGCD_demo1[5141:1322592] 任务4 1
 PPFGCD_demo1[5141:1319371] 任务5 1
 PPFGCD_demo1[5141:1322592] 任务4 2
 PPFGCD_demo1[5141:1319371] 任务5 2
 PPFGCD_demo1[5141:1322592] 任务4 3
 PPFGCD_demo1[5141:1319371] 任务5 3
 PPFGCD_demo1[5141:1322592] 任务4 4
 PPFGCD_demo1[5141:1319371] 任务5 4
 

情景分析:
同步栅栏添加进入队列的时候,当前线程会被锁死,直到同步栅栏之前的任务和同步栅栏任务本身执行完毕时,当前线程才会打开然后继续执行下一句代码。

注意:

在使用栅栏函数时.使用自定义队列才有意义,如果用的是串行队列或者系统提供的全局并发队列,这个栅栏函数的作用等同于一个同步函数的作用

相关文章

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

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

  • iOS gcd栅栏函数dispatch_barrier使用注意

    dispatch_barrier栅栏函数的作用就不用我多说了。常见的使用场景经常1、多线程操作同一数据进行 多读单...

  • 7.3 多线程-GCD

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

  • GCD栅栏函数dispatch_barrier

    需求: 有4个任务, 需要开启多条线程去执行。 有一个特殊任务0, 需要在1,2任务执行完后, 再执行3, 4任务...

  • GCD之Dispatch_barrier(栅栏函数)

    一、定义 异步方法 如果queue为串行队列,该方法可以理解为dispatch_async。 如果queue为并行...

  • iOS多线程梳理-GCD(3)

    上一篇 iOS多线程梳理-GCD死锁 GCD栅栏函数 仅在自己创建的并发队列上有效,在全局(Global)并发队列...

  • iOS 栅栏函数

    转自 https://www.jianshu.com/p/f6b494c19c92 一、什么是栅栏函数 dispa...

  • iOS栅栏函数

    栅栏方法(dispatch_barrier_async):将线程中的任务分割开来。 运行结果 从结果中我们可以看到...

  • GCD-线程栅栏

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

  • GCD-栅栏函数 dispatch_barrier_async

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

网友评论

    本文标题:iOS 多线程GCD-栅栏函数 dispatch_barrier

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