GCD 多线程

GCDGrand Central Dispatch

优点:

>1.利用多核进行并行运算

>2.自动充分使用设备的CPU内核

>3.自动管理线程的生命周期(线程创建、线程调度、线程销毁)


两种任务(执行的block):

1.同步(dispatch_sync):在当前线程中执行,不能开启新线程,按顺序执行。

2.异步(dispatch_async):具备开启新线程的能力,但不一定会开启新线程,可不用等待继续执行。


两种队列(Dispatch Queue):

1.串行队列(Serial Dispatch Queue):每次只执行一个任务,按顺序执行。

2.并发队列(Concurrent Dispatch Queue):多个任务并发执行。并发队列的并发功能只有在异步(dispatch_async)才开启新线程。


系统默认提供两种队列:

主队列:dispatch_get_main_queue() -------- 不可以使用dispatch_sync这个block执行 不死锁卡死。

全局队列:

第一个参数表示队列优先级,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT。第二个参数暂时没用,用0

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)


异步(async)主队列dispatch_get_main_queue(), 不会开启新线程,在主队列中执行任务。

异步(async)+串行队列(Serial),开启一条新线程串行执行。

异步(async)+并发队列(Concurrent),开启新线程,并发执行任务。

同步(sync)➕主队列dispatch_get_main_queue(),锁死。

同步(sync)+串行队列(Serial),没有开启新线程,串行执行任务。

同步(sync)+并发队列(Concurrent),没有开启新线程,在当前线程中串行执行任务。


 >同步不具备开启新线程的能力,串行是按顺序执行的,所以只有异步+并发才开启多条线程,异步+串行会开一条串行执行,其他同步相关的都不会开启新线程。


栅栏方法--- 


    dispatch_async(queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"1------%@",[NSThreadcurrentThread]);

        }

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            sleep(20);

//            这个异步不受 dispatch_barrier_async 和 dispatch_barrier_sync 的控制,

            NSLog(@"5------%@",[NSThreadcurrentThread]);

        });

    });


    dispatch_async(queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"2------%@",[NSThreadcurrentThread]);

        }

    });

    dispatch_barrier_async(queue, ^{

        sleep(5);

        NSLog(@"--异步--barrier-----%@", [NSThread currentThread]);

//        aa 先打印 所以 异步的 barrier会先执行后面的任务(先插入后面的队列) 再执行自己的任务

    });


    NSLog(@"aa, %@", [NSThread currentThread]);

    dispatch_async(queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"3------%@",[NSThreadcurrentThread]);

        }

    });

    dispatch_barrier_sync(queue, ^{

        sleep(5);

        NSLog(@"--同步--barrier-----%@", [NSThread currentThread]);

        //        bb cc 后打印 所以 同步的 barrier会执行完自己的任务再执行后面的任务

    });


    NSLog(@"bb, %@", [NSThread currentThread]);

    dispatch_async(queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"4------%@",[NSThreadcurrentThread]);

        }

    });

    NSLog(@"cc, %@", [NSThread currentThread]);


//    2021-12-29 15:32:53.877454+0800 test[26026:3577219] aa, {number = 1, name = main}

//    2021-12-29 15:32:53.877455+0800 test[26026:3577373] 1------{number = 3, name = (null)}

//    2021-12-29 15:32:53.877570+0800 test[26026:3577372] 2------{number = 4, name = (null)}

//    2021-12-29 15:32:53.877589+0800 test[26026:3577373] 1------{number = 3, name = (null)}

//    2021-12-29 15:32:53.877622+0800 test[26026:3577372] 2------{number = 4, name = (null)}

//    2021-12-29 15:32:58.883172+0800 test[26026:3577372] --异步--barrier-----{number = 4, name = (null)}

//    2021-12-29 15:32:58.884079+0800 test[26026:3577372] 3------{number = 4, name = (null)}

//    2021-12-29 15:32:58.884514+0800 test[26026:3577372] 3------{number = 4, name = (null)}

//    2021-12-29 15:33:03.886208+0800 test[26026:3577219] --同步--barrier-----{number = 1, name = main}

//    2021-12-29 15:33:03.886802+0800 test[26026:3577219] bb, {number = 1, name = main}

//    2021-12-29 15:33:03.887395+0800 test[26026:3577219] cc, {number = 1, name = main}

//    2021-12-29 15:33:03.887629+0800 test[26026:3577372] 4------{number = 4, name = (null)}

//    2021-12-29 15:33:03.888017+0800 test[26026:3577372] 4------{number = 4, name = (null)}

//    2021-12-29 15:33:13.883409+0800 test[26026:3577373] 5------{number = 3, name = (null)}



GCD队列组(dispatch_group)

dispatch_group_notify

监听group中的任务执行结束后 通知 dispatch_group_notify 处理任务。(等待多个耗时异步任务完成后执行新的任务)


//    DISPATCH_QUEUE_CONCURRENT 并发 async 异步 可开启多条新线程

    dispatch_queue_t queue= dispatch_queue_create("net.test.queue", DISPATCH_QUEUE_CONCURRENT);

    dispatch_group_t group = dispatch_group_create();

//

    dispatch_group_enter(group);

    dispatch_group_async(group, queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"1------%@",[NSThreadcurrentThread]);

        }


//        这个异步 不受单独的 notify控制 模拟 AFNetworking的网络请求,需要配合 enter和leave 它俩成对出现,如果只写 enter 没有写leave dispatch_group_notify就一直不会被调用,如果只写leave 不写enter 会崩溃

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            sleep(10);

            NSLog(@"5------%@",[NSThreadcurrentThread]);

            dispatch_group_leave(group);

        });

    });

    dispatch_group_async(group, queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"2------%@",[NSThreadcurrentThread]);

        }

    });

    dispatch_group_async(group, queue, ^{

        for(inti =0; i <2; i++) {

            NSLog(@"3------%@",[NSThreadcurrentThread]);

        }

    });

    dispatch_group_notify(group, queue, ^{

        NSLog(@"end------%@",[NSThread currentThread]);

    });


//    2021-12-29 15:44:07.865654+0800 test[26044:3581038] 1------{number = 3, name = (null)}

//    2021-12-29 15:44:07.865830+0800 test[26044:3581037] 2------{number = 6, name = (null)}

//    2021-12-29 15:44:07.865912+0800 test[26044:3581037] 2------{number = 6, name = (null)}

//    2021-12-29 15:44:07.866085+0800 test[26044:3581039] 3------{number = 4, name = (null)}

//    2021-12-29 15:44:07.866090+0800 test[26044:3581038] 1------{number = 3, name = (null)}

//    2021-12-29 15:44:07.866282+0800 test[26044:3581039] 3------{number = 4, name = (null)}

//    2021-12-29 15:44:17.872043+0800 test[26044:3581038] 5------{number = 3, name = (null)}

//    2021-12-29 15:44:17.872754+0800 test[26044:3581038] end------{number = 3, name = (null)}




GCD 的信号量(Semaphore)

->持有计数的信号。判断信号量count是否大于0,大于0继续执行同时信号量-1进入等待


    //    DISPATCH_QUEUE_CONCURRENT 并发 async 异步 可开启多条新线程

    dispatch_queue_t queue= dispatch_queue_create("net.test.queue", DISPATCH_QUEUE_CONCURRENT);

    //    >=0 可通过

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); //semaphore = 1  可以用作串行 或者加锁。大于 1 例如 2 可控制并发数量

    dispatch_async(queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"1--start----%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"1---end---%@",[NSThread currentThread]);

        //        这个异步模拟 AFNetworking的网络请求,

        dispatch_async(dispatch_get_global_queue(0, 0), ^{


            NSLog(@"5--start----%@",[NSThreadcurrentThread]);

            sleep(10);

            NSLog(@"5---end---%@",[NSThreadcurrentThread]);

            dispatch_semaphore_signal(semaphore);//semaphore + 1

        });

    });


    dispatch_async(queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"2---start---%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"2---end---%@",[NSThread currentThread]);

        dispatch_semaphore_signal(semaphore); //semaphore + 1

    });


    dispatch_async(queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"3---start---%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"3---end---%@",[NSThread currentThread]);

        dispatch_semaphore_signal(semaphore); //semaphore + 1

    });

    dispatch_async(queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"4---start---%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"4---end---%@",[NSThread currentThread]);

        dispatch_semaphore_signal(semaphore); //semaphore + 1

    });

//   

//    2021-12-29 16:12:50.430879+0800 test[26123:3593064] 1--start----{number = 4, name = (null)}

//    2021-12-29 16:12:51.452075+0800 test[26123:3593064] 1---end---{number = 4, name = (null)}

//    2021-12-29 16:12:51.452460+0800 test[26123:3593064] 5--start----{number = 4, name = (null)}

//    2021-12-29 16:13:01.458350+0800 test[26123:3593064] 5---end---{number = 4, name = (null)}

//    2021-12-29 16:13:01.459085+0800 test[26123:3593062] 2---start---{number = 3, name = (null)}

//    2021-12-29 16:13:02.464750+0800 test[26123:3593062] 2---end---{number = 3, name = (null)}

//    2021-12-29 16:13:02.465406+0800 test[26123:3593070] 3---start---{number = 10, name = (null)}

//    2021-12-29 16:13:03.470995+0800 test[26123:3593070] 3---end---{number = 10, name = (null)}

//    2021-12-29 16:13:03.471634+0800 test[26123:3593065] 4---start---{number = 11, name = (null)}

//    2021-12-29 16:13:04.477316+0800 test[26123:3593065] 4---end---{number = 11, name = (null)}




group+semaphore可实现异步顺序调用


    //    DISPATCH_QUEUE_CONCURRENT 并发 async 异步 可开启多条新线程

    dispatch_queue_t queue= dispatch_queue_create("net.test.queue", DISPATCH_QUEUE_CONCURRENT);

    dispatch_group_t group = dispatch_group_create();

    //    >=0 可通过

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); //semaphore = 1  可以用作串行 或者加锁。大于 1 例如 2 可控制并发数量

    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"1--start----%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"1---end---%@",[NSThread currentThread]);

        //        这个异步模拟 AFNetworking的网络请求,

        dispatch_async(dispatch_get_global_queue(0, 0), ^{


            NSLog(@"5--start----%@",[NSThreadcurrentThread]);

            sleep(10);

            NSLog(@"5---end---%@",[NSThreadcurrentThread]);

            dispatch_semaphore_signal(semaphore);//semaphore + 1

        });

    });


    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"2---start---%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"2---end---%@",[NSThread currentThread]);

        dispatch_semaphore_signal(semaphore); //semaphore + 1

    });


    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"3---start---%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"3---end---%@",[NSThread currentThread]);

        dispatch_semaphore_signal(semaphore); //semaphore + 1

    });

    dispatch_group_async(group, queue, ^{

        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);//semaphore - 1

        NSLog(@"4---start---%@",[NSThread currentThread]);

        sleep(1);

        NSLog(@"4---end---%@",[NSThread currentThread]);

        dispatch_semaphore_signal(semaphore); //semaphore + 1

    });

    dispatch_group_notify(group, queue, ^{

        NSLog(@"end------%@",[NSThread currentThread]);

    });


//    2021-12-29 16:18:08.689161+0800 test[26127:3594185] 1--start----{number = 6, name = (null)}

//    2021-12-29 16:18:09.725393+0800 test[26127:3594185] 1---end---{number = 6, name = (null)}

//    2021-12-29 16:18:09.725805+0800 test[26127:3594192] 5--start----{number = 7, name = (null)}

//    2021-12-29 16:18:19.731812+0800 test[26127:3594192] 5---end---{number = 7, name = (null)}

//    2021-12-29 16:18:19.732540+0800 test[26127:3594186] 2---start---{number = 5, name = (null)}

//    2021-12-29 16:18:20.738224+0800 test[26127:3594186] 2---end---{number = 5, name = (null)}

//    2021-12-29 16:18:20.738990+0800 test[26127:3594191] 3---start---{number = 11, name = (null)}

//    2021-12-29 16:18:21.744409+0800 test[26127:3594191] 3---end---{number = 11, name = (null)}

//    2021-12-29 16:18:21.745058+0800 test[26127:3594183] 4---start---{number = 3, name = (null)}

//    2021-12-29 16:18:22.746883+0800 test[26127:3594183] 4---end---{number = 3, name = (null)}

//    2021-12-29 16:18:22.747554+0800 test[26127:3594183] end------{number = 3, name = (null)}


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

推荐阅读更多精彩内容

  • 1. GCD 简介 2. GCD 任务和队列 3. GCD 的使用步骤 4. GCD 的基本使用(6种不同组合区别...
    疯狂的木头人阅读 592评论 0 1
  • GCD 1.进程与线程分别是什么意思? 1.进程是一个具有一定独立功能的程序关于某次数据集合的一次运行活动,它是操...
    IFeng_iOSer阅读 470评论 0 0
  • 【Xcode-Men】Hi,我们团队的井小二童鞋给我们取了个队名:Xcode-Men,简称X-Men,是不是屌屌的...
    知识小集阅读 5,939评论 20 41
  • 简介:为什么要用 GCD 呢?因为 GCD 有很多好处啊,具体如下:GCD 可用于多核的并行运算GCD 会自动利用...
    WorldPeace_hp阅读 382评论 0 4
  • 转载于作者:行走少年郎 原地址 链接:https://www.jianshu.com/p/2d57c72016c6...
    WSWshallwe阅读 262评论 0 0