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

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