GCD

作者: 愤怒的八哥 | 来源:发表于2019-02-13 13:02 被阅读2次
    类型 API名称 说明
    任务提交方式 dispatch_sync 同步提交任务到目标队列,等待任务完成再返回
    dispatch_async 异步提交任务到目标队列,无需等待任务执行,立即返回
    队列类型 Serial Dispatch Queue 等待现在执行中处理结束,任务串行执行
    Concurrent Dispatch Queue 不等待现在执行中处理结束,任务并行执行
    创建队列 dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL) 创建串行队列
    dispatch_queue_create("com.concurrent.queue", DISPATCH_QUEUE_CONCURRENT) 创建并行队列
    更改队列优先级 dispatch_set_target_queue 1、创建的队列默认是(Default Priority),更该创建的队列的优先级别 2、更改队列的执行层级
    延时 dispatch_after 粗略延时执行任务,严格时间要求会出现问题(如何精准延时?)
    并行同步 Dispatch Group 实现并行任务全部处理完毕然后执行结束处理
    dispatch_group_notify 任务全部执行完毕通知
    dispatch_group_wait 堵塞当前线程,等待指定的时间,然后返回
    栅栏 dispatch_barrier_sync 同步提交barrier block,等待之前加到队列中的任务完成,然后执行barrier block,完成后执行后续任务
    dispatch_barrier_async 异步提交barrier block,立即返回,队列中之后加入的任务,等待barrier block完成,然后开始执行后续任务
    多次执行任务 dispatch_apply 多次执行任务,同步等待执行结束,建议在dispatch_async非同步执行
    队列暂停/继续 dispatch_suspend 追加到队列中尚未执行的处理在只后停止
    dispatch_resume 恢复队列继续执行
    信号量 Dispatch Semaphore 持有计数的信号
    dispatch_semaphore_wait 信号量计数减1,只有信号量大于0,此方法才不等待,否则等待指定的时间
    dispatch_semaphore_signal 信号量计数加1
    任务执行只执行一次 dispatch_once 保证任务只被执行一次,线程安全,实现单利
    调度事件源 其CPU负荷非常小,尽量不占用资源。kqueue可以说是应用程序处理XUN内核中发生的各种事件的方法中最优秀的一种。
    时间 dispatch_walltime 绝对时间
    dispatch_time 相对时间

    注意
    如果你部署的最低目标是 iOS 6.0 or Mac OS X 10.8 或者更高的
    ARC已经能够管理GCD对象了,这时候,GCD对象就如同普通的OC对象一样,不应该使用dispatch_retain 或者dispatch_release 。

    系统线程
    主线程:

    dispatch_get_main_queue()
    

    全局并行线程:

    四种优先级:
    `DISPATCH_QUEUE_PRIORITY_HIGH`
    `DISPATCH_QUEUE_PRIORITY_DEFAULT`(默认)
    `DISPATCH_QUEUE_PRIORITY_LOW`
    `DISPATCH_QUEUE_PRIORITY_BACKGROUND`
    线程并不能保证实时性,因此只从优先级只是大致判断。
    后台优先级最低,通常用来执行可有可无的任务。
    dispatch_get_global_queue
    

    GCD常见问题

    1、获取当前队列

    dispatch_queue_set_specific
    dispatch_get_specific
    
    // dispatch_get_specific取出当前队列标识,如果是在当前队列就执行,非当前队列,就异步执行,防止死锁
        if (dispatch_get_specific(queueTag))
            block();
        else
            dispatch_async(queue, block);
    

    注意
    Apple在iOS6废弃dispatch_get_current_queue()函数。

    2、同步提交到队列中,是否一定开启新线程?
    不是。
    As an optimization, this function invokes the block on the current thread when possible.
    3、并行队列开启的线程数是否有限制?
    是的,内核决定了应当使用的线程数,并只生成所需的线程执行处理。
    4、死锁的情况

    在当前队列中同步提交到当前队列
     currentQueue
     dispatch_sync(currentQueue, ^{
            NSLog(@"%@",[NSThread currentThread]);
        });
    因此使用dispatch_get_specific,判断是否是当前队列,防止同步提交任务死锁。
    

    5、事件源
    1、定时器

    优点:
    可以暂停、取消,时间相对精确
        //1.创建类型为 定时器类型的 Dispatch Source
        //1.1将定时器设置在主线程
        _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
        //1.2设置定时器每一秒执行一次
        dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1ull * NSEC_PER_SEC, 0);
        //1.3设置定时器执行的动作
        dispatch_source_set_event_handler(_timer, ^{
            //在这里实现业务逻辑...
        });
        //2.启动定时器
        dispatch_resume(_timer);
    

    2、

    DISPATCH_SOURCE_TYPE_READ 可读取文件映像
    DISPATCH_SOURCE_TYPE_WRITE 可写入文件映像
    CocoaAsyncSocket中使用读写stream流
        readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, socketFD, 0, socketQueue);
        writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, socketFD, 0, socketQueue);
    

    6、线程同步
    1、使用同步队列
    2、使用Dispatch Group
    7、信号量
    使用信号量作为多线程访问的颗粒控制。

    相关文章

      网友评论

          本文标题:GCD

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