线程优先级反转和自旋锁

最近在面试的过程中让我突然线程优先级反转和自旋锁的关系有了一个新的认识。

优先级反转

线程优先级反转问题(Priority Inversion)即当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,而这个低优先级任务在访问共享资源时可能又被其它一些中等优先级任务抢先,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。

关于线程优先级反转可以参考【优先级反转那点事儿】。

优先级反转的问题一般可以通过调整线程的优先级得到解决:

  • 优先级天花板(Priority Ceiling)
  • 优先级继承(Priority Inheritance)

自旋锁

自旋锁是一种线程同步机制,在等待锁的过程中,线程会不断地轮询锁的状态(忙等待),直到获得锁为止。

自旋锁的优点是可以避免线程的阻塞和唤醒,从而减少了线程上下文切换的开销。但是自旋锁不能很好地应对长时间占用锁的情况,可能会导致其他线程无法及时获得 CPU 时间片,影响系统的并发性,并且在高竞争的情况下可能会导致 CPU 占用率过高,影响系统的性能。

自旋锁一般都是针对比较轻量的任务使用的,在 iOS 中一般就是对属性的 atomic 修饰,weak 的实现等这些轻量的任务使用自旋锁。

自旋锁不安全的原因是由于 iOS 的线程调度器和 QOS 的原因可能会导致低优先级的线程最终不会被执行。线程调度器总是优先考虑给 QOS 中较高等级中可运行的线程,而不是低等级的线程。由于在自旋锁上旋转的线程总是可运行的,这意味着如果有足够多的高 QOS 线程在等待一个由低 QOS 线程持有的锁,拥有该锁的线程将永远不会执行。

优先级反转和自旋锁的关系

其实我们可以发现优先级反转其实跟自旋锁没有关系,但是为什么在 iOS 面试中总是会把自旋锁和优先级反转放在一起来说呢?这是因为一旦出现优先级反转问题,自旋锁会让优先级反转问题不容易解决,甚至造成更严重的线程等待问题

参考资料:

  1. https://zhuanlan.zhihu.com/p/146132061
  2. https://forums.swift.org/t/thread-safety-of-weak-properties/422/12