zoukankan      html  css  js  c++  java
  • iOS:多线程的详细介绍

    多线程:
    一、概念
    1、什么是进程?
        程序的一次性执行就是进程。进程占独立的内存空间。
     
    2、什么是线程?
        进程中的代码的执行路径。
     
    3、进程与线程之间的关系?
         每个进程都要创建一个线程,叫主线程。主线程是其他所有线程的父线程。多个线程共享进程之间的内存空间。
     
    4、单核与多核处理器下多线程的不同?
         单核处理器:一个cpu是分时间片轮流执行不同的线程,在切换线程时需要保存和恢复系线程的上下文(cpu中寄存器的内容)。
         多核处理器:多个cpu可以同时执行不同的线程。
     
    5、多线程中线程同步的问题?
         多个线程对同一资源出现竞争的情况下会出现线程同步的问题。
         解决办法:加锁lock、条件condition、信号量semaphore(生产者消费者问题)
     

    二、3种多线程技术对比

    1.NSThread
    2.NSOperation
    3.GCD —— Grand Central Dispatch,是基于C语言的框架

    以上这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。但是就目前而言,iOS的开发者,需要了解三种多线程技术的基本使用过程。因为很多框架技术分别使用了不同多线程技术。例如NSURLConnection的异步静态方法:sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)

    •NSThread:
    优点:NSThread 比其他两个轻量级,使用简单
    缺点:需要自己管理线程的生命周期、线程同步。线程同步对数据的加锁会有一定的系统开销
    •NSOperation:
    不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
    •GCD:
    Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术,用途广泛,苹果公司极力推崇的一个框架。
         

    三、创建线程的主要3种方式

           创建线程方法:
    1.+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
    2.- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
    3.继承NSThread类,然后在子类中重写父类的执行线程的main方法。
     
    •参数说明:
    selector:线程执行的方法,只能有一个参数,不能有返回值
    target:selector消息发送的对象
    argument:传输给target的唯一参数,也可以是nil
    •NSObject直接加入了多线程的支持,允许对象的某个方法在后台运行(本方法普遍应用在游戏中,利用多线程播放声音)
     - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
     

    四、NSThread的使用

    •当涉及到共享资源争夺时,共享资源的数据加锁是一个难点,既要保证数据安全,又要保证线程执行效率
    –使用前加锁
    –尽快使用
    –使用完解锁
    –再去做其他的事情
    •多线程编写顺序
    1.单个方法调试OK
    2.单个线程调试OK
    3.增加线程,并考虑线程加锁、解锁的准确位置。
    •注意:
    –只有主线程能够修改UI
    –如果不涉及到内存争抢,NSThread写多线程是最简单的
    •当不涉及共享资源争夺时,使用NSObject的performSelectorInBackground方法可以非常的方便地实现多线程
     

    五、 NSOperation & NSOperationQueue的使用     

    •NSOperation的两个子类
    1.NSInvocationOperation
    2.NSBlockOperation
    3.子类化NSOperation,然后重写main方法
    •工作原理:
    1.用NSOperation封装要执行的操作
    2.将创建好的NSOperation对象放NSOperationQueue中
    3.启动OperationQueue开始新的线程执行队列中的操作
    •注意事项:
    1.使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢
    2.使用以下方法可以控制并发的线程数量:

    - (void)setMaxConcurrentOperationCount:(NSInteger)cnt

    •使用小结:

    •NSOperation中无需使用线程锁

    •除更新UI之外,对共享资源的争夺也需放在主线程队列之中

    •将定义的操作添加至队列之后,多线程便开始启动

    •NSBlockOperation的使用相比NSInvocationOperation更加灵活、方便

    •通过setMaxConcurrentOperationCount方法可以控制并发的最大线程数量

    六、GCD的使用

    •GCD是基于C语言的框架
    •工作原理:
    –让程序平行排队的特定任务,根据可用的处理资源,安排它们在任何可用的处理器上执行任务
    –要执行的任务可以是一个函数或者一个block
    –底层是通过线程实现的,不过程序员可以不必关注实现的细节
    –GCD中的FIFO队列称为dispatch queue,可以保证先进来的任务先得到执行
    –dispatch__notify可以实现监听一组任务是否完成,完成后得到通知
    •dispatch queue:
    1.Main dispatch queue:是全局可用的队列,用于在主线程上执行任务
    2.Serial:同时只执行一个任务
    3.Concurrent:可以并发地执行多个任务,但是执行完成的顺序是随机的
     
    •使用小结:
    •GCD的原理和Operation非常相像,只是它是C语言架构的。
    •GCD中无需使用线程锁
    •除更新UI之外,对共享资源的争夺也需放在主调度队列之中
    •将任务添加至群组,并指定全局操作队列,使得GCD的多线程更加灵活、方便
    •dispatch_group_notify可以监听一组任务是否完成。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后,才通知界面说已经完成
    •如果不需要监听一组任务,可以直接使用dispatch_async方法

    最后建议:

    •关于多线程必须记住的三个要点
    –只能在主线程中更新UI
    –共享数据争夺的处理
    –不要使用多种多线程技术去争夺同一个资源!
    •在使用多线程的时候,是为了处理并发操作的。如果有可能,我们不要去做抢资源的事情!

     

     
  • 相关阅读:
    poj 1265 Area(Pick定理)
    poj 2954 Triangle(Pick定理)
    poj 1654 Area(多边形面积)
    bzoj 1069 [SCOI2007]最大土地面积(旋转卡壳)
    227 用栈模拟汉诺塔问题
    213 字符串压缩
    212 空格替换
    211 字符串置换
    209 First Unique Character in a String
    197 排列序号
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4856923.html
Copyright © 2011-2022 走看看