About GCD group,barrier

关于GCD的理解,可以参看本博另一篇文章

GCD 串行并行/同步异步 理解

dispatch_barrier_async 实现顺序执行。

根据上一篇文章的理解,如果调用 dipatch_async,异步添加到并行队列中,应该是无法控制执行顺序的。
但是通过dipatch_barrier_async可以实现顺序操作。

dispatch_barrier 说明

使用dispatch_barrier将任务加入到并行队列之后,任务会在前面任务全部执行完成之后执行,任务执行过程中,其他任务无法执行,直到barrier任务执行完成


图片摘自小笨狼的漫谈GCD

代码

    dispatch_queue_t Con_Q = dispatch_queue_create("ConcurrentQ", DISPATCH_QUEUE_CONCURRENT);
    dispatch_barrier_async(Con_Q, ^{
        sleep(1);
        NSLog(@"barrier ConQ 1");
    });
    
    dispatch_barrier_async(Con_Q, ^{
        sleep(1);
        NSLog(@"barrier ConQ 2");
    });
    
    dispatch_barrier_async(Con_Q, ^{
        NSLog(@"barrier ConQ 3");
    });
    
    NSLog(@"barrier 完成");
  • 打印出来的结果,并行队列中的代码是按顺序执行的(NSlog肯定会先执行,因为是async,这里和我们说的队列中的顺序执行没有冲突)
2016-06-17 16:03:22.771 GCD_Group[28565:1718338] barrier 完成
2016-06-17 16:03:23.774 GCD_Group[28565:1718384] barrier ConQ 1
2016-06-17 16:03:24.780 GCD_Group[28565:1718384] barrier ConQ 2
2016-06-17 16:03:24.780 GCD_Group[28565:1718384] barrier ConQ 3
  • 队列必须是自行创建的串行/并行队列,才可以达到顺序执行的效果。注意,用主队列(get_main_queue)还是会阻塞主线程
    // 自定义串行队列
    dispatch_queue_t Se_Q = dispatch_queue_create("serialQ", DISPATCH_QUEUE_SERIAL);
    // 自定义并行队列
    dispatch_queue_t Con_Q = dispatch_queue_create("ConcurrentQ", DISPATCH_QUEUE_CONCURRENT);
    // 主队列
    dispatch_queue_t MainQ = dispatch_get_main_queue();
    // 全局队列
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

结论:

除了全局队列以外,剩余三种方式,都可以实现队列内的代码顺序执行。


dispatch_group 相关操作

理解

dipatch_group 相当于规定数个 blocks为group.

  • 假设一个队列中一共有5个block,我将其中的4个通过dipatch_group添加到一个队列中,那么我就可以通过下面的操作控制他们,并且知道他们完成的节点。
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // ---------------dipatch_group------------
    dispatch_group_async(gp, globalQueue, ^{
        sleep(2);
        NSLog(@"globalQueue1");
    });
    
    dispatch_group_async(gp, globalQueue, ^{
        dispatch_group_wait(gp, dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC));
        NSLog(@"globalQueue2");
    });

    dispatch_group_async(gp, globalQueue, ^{
        NSLog(@"globalQueue3");
    });
    
    dispatch_group_notify(gp, globalQueue, ^{
        NSLog(@"globalQueue 已完成");
    });
    
    dispatch_async(globalQueue, ^{
        sleep(8);
        NSLog(@"globalQueue4");
    });

日志:

2016-06-17 16:15:42.858 GCD_Group[28700:1730502] globalQueue3
2016-06-17 16:15:46.199 GCD_Group[28700:1730486] globalQueue1
2016-06-17 16:15:46.199 GCD_Group[28700:1730494] globalQueue2
2016-06-17 16:15:46.200 GCD_Group[28700:1730494] globalQueue 已完成
2016-06-17 16:15:50.863 GCD_Group[28700:1730505] globalQueue4

说明

  • 这里和采用哪个队列没有多大关系,和上面的barrier不同。
  • 阻塞一个block有两种方法:
    • sleep(n) 全局的时间休眠定时器。
  dispatch_group_wait(gp, dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC));

这个 group wait 函数只会阻塞当前 group block 里面的程序,从日志中可以看出,globalQueue3 先执行了,说明这里的等待不会阻塞所有的block.

  • group 完成时,会调用
dispatch_group_notify(group,queue,block) {}

来执行中间的内容。

dispatch_group_enter(group)、dispatch_group_leave(group)

代码

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(5);
        NSLog(@"任务一完成");
        dispatch_group_leave(group);
    });
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(8);
        NSLog(@"任务二完成");
        dispatch_group_leave(group);
    });
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"任务完成");
    });

说明

其实很好理解。 enter 和 leave 必须是成对出现的。相当于引用计数,在enter的时候+1,leave的时候-1.

  • dispatch_group_enter(group); 是告诉说下面添加的block要添加到 group中
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容