iOS关于锁安全的几个知识点
1、atomic 真的是100%线程安全吗?
atomic属性修饰符保证该属性的setter,getter方法的操作具有原子性,从而被修饰的属性是线程安全的。但是不能保证包含这个属性的对象实例是线程安全的。
想要绝对的线程安全就用@synchronized、NSLock、dispatch_semaphore、pthread_mutex(pthread_mutex(recursive))、OSSplinLock(自旋锁)、os_unfari_lock.
2、@synchroniezd的效率最低但使用最方便,OSSplinkLock效率最高,但是OSSplinLock已不再安全,为什么?苹果的替代方案是什么?
OSSpinlLock的问题:如果一个低优先级的线程获得锁并访问共享资源,这时一个高优先级的线程也尝试获得这个锁,它会处于 spin lock 的忙等状态从而占用大量 CPU。此时低优先级线程无法与高优先级线程争夺 CPU 时间,从而导致任务迟迟完不成、无法释放 lock。
苹果给在iOS 10之后提供了 os_unfair_lock
//声明一个锁
os_unfair_lock_t unfairLock;
//尝试加锁
unfairLock = &(OS_UNFAIR_LOCK_INIT);
//加锁
os_unfair_lock_lock(unfairLock);
//解锁
os_unfair_lock_unlock(unfairLock);
3、举例说明多线程编程中优先级反转的问题。
示例:
假如有高A-中B-低C 3种优先级的线程,t1时刻低优先级的线程C先获取了一个共享资源S,t2时刻,高优先级的线程A尝试获取资源S,但是线程C还在占用资源S,所以A就被挂起了。这时B就有了最高可运行优先级,B在C运行完之后会立即获取到资源S(A还在挂起状态),B继续占有S运行,期间A会继续间隔尝试获取S,但是得不到S无法运行,期间C若要再次运行,他没有B的优先级高也得不到S.所以优先级排序ABC变成了BAC。也就是优先级反转
图:iOS中各种锁的效率比较【引自ibireme博客】: