iOS中的常见多线程方案
image.pngGCD中的2个用来执行任务的函数
- 用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue , dispatch_block_t block);
queue : 队列
block : 任务
- 用异步的方式执行任务
dispatch_async(dispatch_queue_t queue , dispatch_block_t block);
GCD队列
- 并发队列
- 可以让多个任务并发(同时)执行 (自动开启多个线程同时执行任务)
- 并发功能只有在异步(dispatch_async)函数下才有效
- 串行队列
- 让任务一个接一个的执行
各种队列的执行效果
image.png死锁
image.png NSLog(@"执行任务1");
//队列的特点 :排队 FIFO
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"执行任务2");
});
// dispatch_sync :立马在当前线程执行任务,执行完毕才能继续往下执行
//任务2需要等任务3执行完才能执行 而任务3需要等任务2完成 所以死锁了
NSLog(@"执行任务3");
- 使用sync函数往当前串行队列中添加任务,就会卡在当前的串行队列,产生死锁
队列组
https://www.jianshu.com/p/5dea282fe042
安全隐患
- 资源共享
- 一块资源可能被多个线程共享,也就是多个线程可能会同时访问同一块资源
- 容易引起 数据错乱和数据安全 问题
解决方案
- 使用线程同步技术 (按照设定的先后顺序执行)
- 常用线程同步技术 : 加锁
- OSSpinLock
- os_unfair_lock
- pthread_mutex
- dispatch_semaphore
- dispatch_queue(DISPATCH_QUEUE_SERIAL)
- NSLock
- NSRecursiveLock
- NSCondition
- NSConditionLock
-@synchronized
OSSpinLock
- 自旋锁 ,等待所的线程会处于忙等状态(busy-wait),一直占用着CPU 资源
//iOS 10 以后废弃了这个
#import <libkern/OSAtomic.h>
@property(assign,nonatomic) OSSpinLock lock;
self.lock = OS_SPINLOCK_INIT; //初始化
OSSpinLockLock(&_lock); //加锁
OSSpinLockUnlock(&_lock); //开锁
- 目前已经不再安全 ,可能会出现优先级反转的问题
在时间片轮转过程中 可能会导致低优先级的线程 加锁变成高优先级的 原来的高优先级的进不来 成了低优先级的
OS_unfair_lock
- 用于取代不安全的OSSpinLock ,iOS10开始
- 从底层调用看,等待os_unfair_lock锁的线程会处于休眠状态,而不是忙等
-
#import <os/lock.h>
image.png
pthread_mutex
- mutex 叫做互斥锁 ,等待锁的线程会处于休眠状态
-
#import<pthread.h>
image.png
image.png
pthread_mutex 条件
image.pngNSLock ,NSRecursiveLock
-
NSLock是对mutex普通锁的封装
image.png
- NSRecursiveLock 也是对mutex递归锁的封装,API和NSLock基本一致
NSCondition
-
是对mutex 和cond的封装
image.png
网友评论