美文网首页
iOS 多线程小结

iOS 多线程小结

作者: percivals | 来源:发表于2020-12-15 16:58 被阅读0次

    在 iOS 中其实目前有 4 套多线程方案,他们分别是:Pthreads、NSThread、GCD、 NSOperation & NSOperationQueue

    Pthreads:常用于各种操作系统,基于c语言的框架,一般不用到

    NSThread:手动管理生命周期,多用于调试使用

    GCD: 分为任务和队列, 优势:底层实现,运行速度快

    任务为要执行的代码,以block表示,分为同步任务和异步任务,同步任务会阻塞当前线程

    1.队列分为串行和并行,串行队列一步步执行

    2.队列组:将很多队列添加到一个队列组中,当组内所有任务执行完毕,有一个方法可以通知我们

    串行队列:dispatch_queue_t queue = dispatch_queue_create(“nameID”,DISPATCH_QUEUE_SERIAL);

    并行队列:dispatch_queue_t queue = dispatch_queue_create(“nameID”,DISPATCH_QUEUE_CONCURRENT);

    串行队列中,系统提供了一个主队列:
    dispatch_queue_t queue = dispatch_get_main_queue()

    并行队列中,系统提供了一个全局并发队列:
    dispatch_queue queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)

    同步执行任务:
    dispatch_sync(queue,^{
    // 任务代码
    })

    异步执行任务:
    dispatch_async(queue,^{
    // 任务代码
    })

    注意:同步执行+主队列 在主线程中调用会死锁

    3.栅栏方法

    在一个队列中,栅栏任务会在之前任务执行完毕后执行,后续任务会在栅栏任务执行完毕后执行,即排序 任务一、任务二、栅栏任务、任务三、任务四的执行结果是 任务一、任务二异步执行,待执行完两者再执行栅栏任务,执行完毕再异步执行任务三、任务四

    dispatch_barrier_async(queue,^{
    // 栅栏任务
    })

    4.延时方法

    在指定时间之后将任务添加到队列中

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0*NSEC_PER_SEC)), queue,^{
    // 延时任务
    })

    5.只执行一次代码

    保证某段代码在程序运行过程中只被执行一次,保证线程安全

    如单例:

    -(instance)shareManager
    {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
    //只执行一次的代码

        _manager = [[Manager alloc] init];
    });
    
    return _manager;
    

    }

    6.线程组(队列组) dispatch_group

    任务放到队列中,队列放到队列组中

    dispatch_group_t group = dispatch_group_creat();

    dispatch_group_async(group,queue,^{
    // 任务1
    })

    dispatch_group_async(group,queue,^{
    // 任务2
    })

    监听线程组内任务全部执行完毕 dispatch_group_notify

    dispatch_group_notify(group,queue,^{
    // 监听线程组内任务执行完毕后执行的任务
    });

    7.线程阻塞 dispatch_group_enter、dispatch_group_leave

    阻塞线程等待前面的线程组内的任务执行完

    dispatch_group_wait(group,DISPATCH_TIME_FOREVER);

    dispatch_group_enter 标志着一个任务追加到 group,执行一次,相当于 group 中未执行完毕任务数+1
    dispatch_group_leave 标志着一个任务离开了 group,执行一次,相当于 group 中未执行完毕任务数-1。

    当 group 中未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞,以及执行追加到dispatch_group_notify中的任务。

    8.信号量 dispatch_semaphore

    •   保持线程同步,将异步执行任务转换为同步执行任务
    •   保证线程安全,为线程加锁
    

    dispatch_semaphore_create:创建一个Semaphore并初始化信号的总量

    dispatch_semaphore_signal:发送一个信号,让信号总量加1

    dispatch_semaphore_wait:可以使总信号量减1,当信号总量为0时就会一直等待(阻塞所在线程),否则就可以正常执行。

    NSOperation和NSOperationQueue:NSOperation 和 NSOperationQueue 分别对应 GCD 的 任务 和 队列;将要执行的任务封装到一个 NSOperation 对象中,将此任务添加到一个 NSOperationQueue 对象中

    NSOperation 只是一个抽象类,所以不能封装任务。但它有 2 个子类用于封装任务。分别是:NSInvocationOperation 和 NSBlockOperation 。创建一个 Operation 后,需要调用 start 方法来启动任务

    除了上面的两种 Operation 以外,我们还可以自定义 Operation。自定义 Operation 需要继承 NSOperation 类,并实现其 main() 方法

    任务创建完成后,添加到对应的NSOperationQueue队列中执行

    NSOperation 有一个非常实用的功能,那就是添加依赖
    [operation2 addDependency:operation1];

    单例:

    • (instancetype)sharedTool {
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
      _instance = [[Tool alloc] init];
      });

      return _instance;
      }

    相关文章

      网友评论

          本文标题:iOS 多线程小结

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