美文网首页
GCD的几个浅显API

GCD的几个浅显API

作者: 深海时代 | 来源:发表于2019-01-14 14:55 被阅读0次

    相关书籍的一点笔记

    1. 普通异步追加

    dispatch_async(serialDispatchQueue1, ^{  });

    在某个线程异步追加某个任务;

    2.普通线程创建

    dispatch_queue_tserialDispatchQueue1=dispatch_queue_create("线程1",NULL);

    线程初始化,参数:1,线程名;2.线程类型:串行传Null  并行传:DISPATCH_QUEUE_CONCURRENT;

    多个串行线程之间也是互相并行的。可能会出现多个线程使用一个数据的情况(数据竞争)建议串行线程,否则建议并行线程;

    3.特殊线程

    dispatch_queue_t main_queue=dispatch_get_main_queue();主线程(NSRunLoop)

    更新UI的操作要回调主线程完成,主线程有且仅有一个;

    dispatch_queue_t globalDispatchQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);始终存在的并行线程,每个程序都能获取,不需要创建,有四个优先级

    4.设置线程优先级

    dispatch_set_target_queue(serialDispatchQueue1, globalDispatchQueue);

    将参数1的线程运行到参数2的线程上,获得参数二的优先级,如果参数二为串行线程,那被加到参数二上的线程互相串行执行。(参数1线程自身可以并行)

    5.延时方法

    dispatch_time_t time_t=dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC);

        dispatch_after(time_t, serialDispatchQueue1, ^{  });

    在指定时间追加到某队列,这里是现在开始的1S后;

    6.线程组和线程等待

    dispatch_group_t group=dispatch_group_create();创建方法

     dispatch_group_async(group, serialDispatchQueue1, ^{  });往里添加线程

     dispatch_group_notify(group, dispatch_get_main_queue(), ^{  });线程组结束回调

    线程组结束回调总是在线程组所有线程执行完之后调用;

    BOOL groupDone=dispatch_group_wait(group, DISPATCH_TIME_FOREVER);线程执行情况查询

    0是执行完毕,其他值未执行完毕;第二个参数是超时时间;

    此函数调用时,调用函数的线程会中断等待返回结果或至超时,传DISPATCH_TIME_NOW可以立即返回结果,而传DISPATCH_TIME_FOREVER则一定等待对应线程结束后返回且返回结果恒为0;

    7.栅栏方法

    针对并行线程使用,串行线程本身就是没有栅栏需求的。

     dispatch_barrier_async(serialDispatchQueue1, ^{    });追加到对应线程的栅栏方法

    栅栏方法的功能://(线程同步,并行线程强制串行)

    1)阻塞后续事件的追加,等待已追加事件的完成。

    2)在已追加事件全部完成之后,执行自己的追加方法。

    3)在自己的追加事件完成之后,取消阻塞。

    8.同步追加

    dispatch_sync(serialDispatchQueue1, ^{});同步追加方法

    同步追加类似于线程等待方法,会阻塞执行线程直至追加任务返回,栅栏方法也有同步追加。

    同步追加适用于需要立刻使用返回结果的场景,但要防止线程死锁。

    线程死锁:当一个任务的逻辑执行顺序必须在自己之后,那么死锁。

    比如串行线程执行向自己追加同步任务,会出现线程停下来等自己的情况,这种情况是不可能完成的,所以会死锁,解除死锁只要打破这个逻辑链就好了,采用异步追加或者不要在本线程完成或者追加到并行线程。(并行线程可以等待自己,因为并行线程等待的时候是可以正常执行任务的)

    同步追加和异步追加指的是:要不要阻塞执行追加的线程等待结果回调;

    串行队列和并行队列指的是:追加过去的任务在线程里要不要按次序执行;

    9.批次追加

    dispatch_apply(10, serialDispatchQueue1, ^(size_t index) {});

    同步追加一个任务的N次到指定线程,block提供了当前执行bolck的索引,同时也是同步等待返回,建议用异步追加先追加到并行线程,然后执行完任务线程返回;

    10.线程挂起/恢复

    当一个线程追加大量处理时,可能到某个任务返回后,我要暂停任务等待外部事件结束后再继续处理,这个时候需要线程的挂起与恢复。

    dispatch_suspend(serialDispatchQueue1);线程挂起

     dispatch_resume(serialDispatchQueue1);线程恢复

    挂起不影响已执行与正在执行的任务,但会停止执行尚未执行的任务。

    11.信号量

    信号量用来控制并行任务数量。

    当我对同时执行的任务数量上限有要求时,可以使用信号量来实现,比如100000个任务同时访问同一个数组,如果同时异步执行,会因为数据竞争问题crash。此时用信号量控制并发,分三步:

    1)设置最大信号数量为1。

    dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);//最大信号数量

    2)在每次执行任务的时候宣布占用一个信号。

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    3)在每次执行完任务的时候宣布解除占用信号。

    dispatch_semaphore_signal(semaphore);

    其中宣布占用方法在等待时间为 DISPATCH_TIME_FOREVER 时也是同步等待方法,这个时间可以是另一个超时时间,这取决于需求。

    semaphore是一个0-最大信号数量 的值,取决于剩余信号量,当它大于0时,dispatch_semaphore_wait() 方法返回成功(0),并占用一个信号量使计数减一,当它等于0时,wait方法持续等待至超时。

    dispatch_semaphore_signal() 方法在任务结束后调用,使信号量加一,所有任务完成,信号量回归最大信号数量。

    12.单例

    通过静态计数让代码只运行一次,炒鸡简单好用的API;

    static dispatch_once_t onceToken;

     dispatch_once(&onceToken, ^{});

    自定义单例会存在多线程竞争问题,这个不会;

    13. 数据分割读取(笔者懒癌发作当场去世,尚未演示效果)

    大文件的分割并行处理

    1)创建dispatch_io_t对象

    dispatch_io_t dispatch_io_create( dispatch_io_type_t type, dispatch_fd_t fd, dispatch_queue_t queue, void (^cleanup_handler)(int error));

    创建dispatch_io_t对象,参数依次为:

    1》type 通道类型   DISPATCH_IO_STREAM 0 顺序访问文件,DISPATCH_IO_RANDOM 1

    随机访问文件

    2》fd,文件标识符

    3》queue 错误回调线程

    4》block 错误回调

    2)读写操作

    void dispatch_io_read( dispatch_io_t channel, off_t offset, size_t length, dispatch_queue_t queue, dispatch_io_handler_t io_handler);

    1》channel 读写对象

    2》offset  读写偏移量  DISPATCH_IO_RANDOM 类型的通道有效,指定要读写的文件位置偏移量,而DISPATCH_IO_STREAM忽略此参数,从当前位置读写。

    3》length 分割数据的大小;

    4》queue 分割数据每次读写完毕之后回调的线程;

    5》block  对应回调函数;

    相关文章

      网友评论

          本文标题:GCD的几个浅显API

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