GCD浅析

iOS 多线程
  • 多线程相关概念
    • 进程与线程
      • 进程概念
        进程是程序在计算机上的一次执行活动,打开一个app,就开启了一个进程,可包含多个线程
      • 线程概念
        独立执行的代码段,一个线程同时间只能执行一个任务,反之多线程并发就可以在同一时间执行多个任务
      • 主线程
        主线程(又叫作UI线程)主要任务是处理UI事件,显示和刷新UI,(只有主线程有直接修改UI的能力)耗时的操作放在子线程(又叫作后台线程、异步线程)。在iOS中开子线程去处理耗时的操作,可以有效提高程序的执行效率,提高资源利用率。但是开启线程会占用一定的内存,(主线程的堆栈大小是1M,第二个线程开始都是512KB,并且该值不能通过编译器开关或线程API函数来更改)降低程序的性能。所以一般不要同时开很多线程
    • 线程相关
      • 同步线程
        同步线程会阻塞当前线程去执行线程内的任务,执行完之后才会反回当前线程
      • 异步线程
        异步线程不会阻塞当前线程,会开启其他线程去执行线程内的任务
      • 串行队列
        线程任务按先后顺序逐个执行(需要等待队列里面前面的任务执行完之后再执行新的任务)
      • 并发队列
        多个任务按添加顺序一起开始执行(不用等待前面的任务执行完再执行新的任务),但是添加间隔往往忽略不计,所以看着像是一起执行的, 用于单核CPU
      • 并发VS并行
        并行是基于多核设备的,并行一定是并发,并发不一定是并行
    • 多线程中会出现的问题
      • Critical Section(临界代码段)
        指的是不能同时被两个线程访问的代码段,比如一个变量,被并发进程访问后可能会改变变量值,造成数据污染(数据共享问题)
      • Race Condition (竞态条件)
        当多个线程同时访问共享的数据时,会发生争用情形,第一个线程读取改变了一个变量的值,第二个线程也读取改变了这个变量的值,两个线程同时操作了该变量,此时他们会发生竞争来看哪个线程会最后写入这个变量,最后被写入的值将会被保留下来
      • Deadlock (死锁)
        两个(多个)线程都要等待对方完成某个操作才能进行下一步,这时就会发生死锁
      • Thread Safe(线程安全)
        一段线程安全的代码(对象),可以同时被多个线程或并发的任务调度,不会产生问题,非线程安全的只能按次序被访问
      • Mutable对象非线程安全
        所有Mutable对象都是非线程安全的,所有Immutable对象都是线程安全的,使用Mutable对象,一定要用同步锁来同步访问(@synchronized
      • 互斥锁
        能够防止多线程抢夺造成的数据安全问题,但是需要消耗大量的资源
      • 原子属性(atomic)加锁
        • atomic
          原子属性,为setter方法加锁,将属性以atomic的形式来声明,该属性变量就能支持互斥锁了
        • nonatomic
          非原子属性,不会为setter方法加锁,声明为该属性的变量,客户端应尽量避免多线程争夺同一资源
      • Context Switch (上下文切换)
        当一个进程中有多个线程来回切换时,context switch用来记录执行状态,这样的进程和一般的多线程进程没有太大差别,但会产生一些额外的开销
  • GCD中的三种队列类型
  • GCD中一些系统提供的常用dispatch方法
    • dispatch_after延时添加到队列
      dispatch_time_t delayTime3 = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
      dispatch_time_t delayTime2 = dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC);
      dispatch_queue_t mainQueue = dispatch_get_main_queue();
      NSLog(@"current task");
      dispatch_after(delayTime3, mainQueue, ^{
      NSLog(@"3秒之后添加到队列");
      });
      dispatch_after(delayTime2, mainQueue, ^{
      NSLog(@"2秒之后添加到队列");
      });
      NSLog(@"next task");
    • dispatch_apply在给定的队列上多次执行某一任务,在主线程直接调用会阻塞主线程去执行block中的任务
      • dispatch_apply函数的功能
        把一项任务提交到队列中多次执行,队列可以是串行也可以是并行,dispatch_apply不会立刻返回,在执行完block中的任务后才会返回,是同步执行的函数
      • dispatch_apply正确使用方法
        为了不阻塞主线程,一般把dispatch_apply放在异步队列中调用,然后执行完成后通知主线程
      • 使用示例
        dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
        NSLog(@"current task");
        dispatch_async(globalQueue, ^{
        dispatch_queue_t applyQueue = dispatch_get_global_queue(0, 0);
        //第一个参数,3--block执行的次数
        //第二个参数,applyQueue--block任务提交到的队列
        //第三个参数,block--需要重复执行的任务
        dispatch_apply(3, applyQueue, ^(size_t index) {
        NSLog(@"current index %@",@(index));
        sleep(1);
        });
        NSLog(@"dispatch_apply 执行完成");
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_async(mainQueue, ^{
        NSLog(@"回到主线程更新UI");
        });
        });
        NSLog(@"next task");
      • 嵌套使用dispatch_apply会导致死锁
    • dispatch_once保证在app运行期间,block中的代码只执行一次
      经典使用场景---单例
    • dispatch_barrier_async 栅栏的作用
      • 功能
        是在并行队列中,等待在dispatch_barrier_async之前加入的队列全部执行完成之后(这些任务是并发执行的)再执行dispatch_barrier_async中的任务,dispatch_barrier_async中的任务执行完成之后,再去执行在dispatch_barrier_async之后加入到队列中的任务(这些任务是并发执行的)
      • 使用示例
        dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(conCurrentQueue, ^{
        NSLog(@"dispatch 1");
        });
        dispatch_async(conCurrentQueue, ^{
        NSLog(@"dispatch 2");
        });
        dispatch_barrier_async(conCurrentQueue, ^{
        NSLog(@"dispatch barrier");
        });
        dispatch_async(conCurrentQueue, ^{
        NSLog(@"dispatch 3");
        });
        dispatch_async(conCurrentQueue, ^{
        NSLog(@"dispatch 4");
        });
  • #来自http://www.jianshu.com/p/ae786a4cf3b1  http://blog.csdn.net/huangyongf/article/details/52199175
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值