GCD

作者: iseerain | 来源:发表于2019-11-13 12:58 被阅读0次

Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。
它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。
它是一个在线程池模式的基础上执行的并发任务。
Mac OS X Snow Leopard 10.6中首次推出,也可在 iOS 4及以上版本使用。

  • dispatch_queue: serial / concurrent (main/global)

  • dispatch_sync / dispatch_async

  • dispatch_barrier: sync / async (用在自定义并行队列中)

  • dispatch_group: create async enter leave wait notify

  • dispatch_once

  • dispatch_after

  • dispatch_source timer

  • dispatch_semaphore

  • dispatch_apply

dispatch_queue_create

创建和获取队列

// 创建并发队列
dispatch_queue_t queue = dispatch_queue_create("com.mine.concurrent", DISPATCH_QUEUE_CONCURRENT);

// 创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.mine.serial", DISPATCH_QUEUE_SERIAL);

// 获取全局队列(并发)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 获取主队列(串行)
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync

同步执行任务

for (int i = 0; i < 10; i++) {
    // 同步步执行任务
    dispatch_sync(queue, ^{

        sleep(1);

        NSLog(@"task %d -- %@", i, NSThread.currentThread);
    });
    // 同步调用函数
    dispatch_sync_f(queue, &i, somefunc);
}

// 定义调用的函数
void somefunc(void *_Nullable context) {

    sleep(1);

    int *i = (int *)context;

    // context 可以传 ViewController 对象
    // ViewController *vc = (__bridge ViewController *)(context);

    NSLog(@"this is some function. -- %d", *i);
}
dispatch_async

异步执行任务

for (int i = 0; i < 10; i++) {
    // 异步执行任务
    dispatch_async(queue, ^{

        sleep(1);

        NSLog(@"task %d -- %@", i, NSThread.currentThread);
    });
    // 异步调用函数
    dispatch_async_f(queue, &i, somefunc);
}

// 定义调用的函数
void somefunc(void *_Nullable context) {

    sleep(1);

    int *i = (int *)context;

    // context 可以传 ViewController 对象
    // ViewController *vc = (__bridge ViewController *)(context);

    NSLog(@"this is some function. -- %d", *i);
}
dispatch_barrier

栅栏:在它之前的任务执行结束后它才执行,它之后的任务需要等它执行完成之后才会执行。
注意:queue不能是dispatch_get_global_queue(全局的并发队列)

for (int i = 0; i < 10; i++) {

    dispatch_barrier_async(queue, ^{

        sleep(1);

        NSLog(@"barrier task %d -- %@", i, NSThread.currentThread);
    });
}
dispatch_group

队列组:等多个异步任务都执行完后,再执行某个任务。
dispatch_barrier也可以实现。

dispatch_group_t group = dispatch_group_create();

// 方式一
for (int i = 0; i < 10; i++) {

    dispatch_group_async(group, queue, ^{

        sleep(2);

        NSLog(@"task %d -- %@", i, NSThread.currentThread);
    });
}

// 方式二
for (int i = 0; i < 10; i++) {

    dispatch_group_enter(group);

    dispatch_async(queue, ^{

        sleep(3);

        NSLog(@"task %d -- %@", i, NSThread.currentThread);

        dispatch_group_leave(group);
    });
}

// dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_FOREVER, 0));

dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5));

dispatch_group_notify(group, queue, ^{

    NSLog(@"group notify -- %@", NSThread.currentThread);
});
dispatch_once

只会执行一次

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

    NSLog(@"do once");
});
dispatch_after

延迟执行队列任务

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC * 2)), queue, ^{

    NSLog(@"after ");
});
dispatch_source timer

GCD Timer

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1*NSEC_PER_SEC, 0 * NSEC_PER_SEC);

dispatch_source_set_event_handler(timer, ^{

    NSLog(@"timer -- %@", NSThread.currentThread);
});

dispatch_resume(timer);

self->timer = timer;
dispatch_semaphore

信号量
dispatch_semaphore_create: 创建信号量,设定信号量的初始值。
dispatch_semaphore_signal: 对信号量的值进行加1操作。
dispatch_semaphore_wait: 信号量的值=0时,函数不返回,会一直等待,阻塞当前线程;信号量的值>=1时,对信号量的值减1,继续执行当前任务。

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

//    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

dispatch_async(queue, ^{

     sleep(1);

     NSLog(@"task 1 -- %@", NSThread.currentThread);

     dispatch_semaphore_signal(semaphore);
});

//    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

dispatch_async(queue, ^{

    sleep(3);

    NSLog(@"task 2");

    dispatch_semaphore_signal(semaphore);
});

//    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

dispatch_async(queue, ^{

    sleep(2);

    NSLog(@"task 3");

    dispatch_semaphore_signal(semaphore);
});

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

dispatch_semaphore_signal(semaphore);
dispatch_apply

快速迭代,常用于并发队列中。
无论是在串行队列,还是并发队列中,dispatch_apply都会等待全部任务执行完毕

NSLog(@"apply---begin");

dispatch_apply(10, queue, ^(size_t i) {

     sleep(1);

     NSLog(@"i -- %zu -- %@", i, NSThread.currentThread);
});

NSLog(@"apply---end");

相关文章

  • 多线程之GCD

    GCD介绍 1、GCD简介 2、GCD任务和队列 3、GCD 的基本使用 4、GCD 线程间的通信 5、GCD 的...

  • 扩展GCD(求逆元,解同余方程等等)

    首先要知道gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(|a|,|b|)=gcd(b,a%b)...

  • iOS - GCD

    目录 GCD简介 GCD核心概念 GCD队列的使用 GCD的常见面试题 GCD简介 Grand Central D...

  • iOS-多线程:GCD

    GCD 简介 GCD 任务和队列 GCD 的使用步骤 GCD 的基本使用(6种不同组合区别) GCD 线程间的通信...

  • 浅析GCD

    GCD目录: 1. GCD简介 为什么要用GCD呢? GCD可用于多核的并行运算GCD会自动利用更多的CPU内核(...

  • 7.3 多线程-GCD

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

  • iOS 多线程--GCD

    一、GCD基本介绍 1.GCD简介 GCD是Grand Central Dispatch的缩写,GCD是苹果推出的...

  • 自用算法模板(JAVA版)

    一、数论 1)GCD GCD(求最大公约数) QGCD(快速GCD) extGCD(拓展GCD,解决ax + by...

  • GCD介绍

    一、GCD简单介绍 什么是GCD GCD优势 任务和队列 GCD有2个核心概念 GCD的使用就2个步骤 将任务添加...

  • 7.多线程基础(七)GCD加强

    1.GCD串行队列和并发队列 2.GCD延时执行 3.GCD线程组:(的作用) 4.GCD定时器: GCD的实现 ...

网友评论

      本文标题:GCD

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