深入了解替代单纯回忆

优先级反转

关于优先级反转,参考资料中《优先级反转那点事儿》讲的比较清晰。此处直接贴过来

对iOS中自旋锁与优先级反转(Priority inversion)的了解

  • 线程A在一个比较低的优先级上作业, 假定是10吧。然后在时间点T1的时分,线程A确定了一把互斥锁,并开端操作互斥数据。
  • 这时有个高优线级线程C(比如优先级20)在时间点T2被唤醒,它也也需求操作互斥数据。当它加锁互斥锁时,因为互斥锁在T1被线程A锁掉了,所以线程C扔掉CPU进入阻塞情况,而线程A得以占有CPU,持续实行。
  • 作业到这一步仍是正确的,虽然优先级10的A线程看上去抢了优先级20的C线程的时间,但因为程序逻辑,C的确需求退出CPU等完结互斥数据操作后,才能获得CPU。
  • 可是,假定咱们有个线程B在优先级15上,在T3时间点上醒了过来,因为他比其时实行的线程A优先级高,所以它会当即抢占CPU。而线程A被逼进入READY情况等候。
  • 一向届时间点T4,线程B扔掉CPU,这时优先级10的线程A是仅有READY线程,它再次占有CPU持续实行,最终在T5解锁了互斥锁。
  • 在T5,线程A解锁的瞬间,线程C当即获取互斥锁,并在优先级20上等候CPU。因为它比线程A的优先级高,系统立刻调度线程C实行,而线程A再次进入READY情况。

上面这个时序里,线程B从T3到T4占有CPU运转的行为,便是事实上的优先级反转。一个优先级15的线程B,经过限制优线级10的线程A,而事实上导致高优先级线程C无法正确得到CPU。这段时间是不可控的,因为线程B可以长时间占有CPU(即便轮转时间片届时,线程A和B都处于可实行态,可是因为B的优先级高,它依然可以占有CPU),其成果便是高优先级线程C或许长时间无法得到 CPU。

优先级反转 vs 自旋锁

  • 优先级反转问题的出现跟自旋锁没有关系
  • 不运用自旋锁时也或许出现优先级反转问题。只要是线程或任务有多个优先级,理论上就或许有反转问题
  • 操作系统在优先级反转发生时通常都会有主动的处理方案,比如提凹凸优先级线程的优先级等
  • 在运用iOS中的OSSpinLock
    • 因为这种锁不会记录持有它的线程信息,所有当发生优先级反转时,系统找不到低优先级的线程,或许因而无法经过进步优先级处理优先级反转问题
    • 再加上,高优先级线程运用自旋锁进行轮训等候锁时在一向占用CPU时间片,使得低优先级线程拿届时间片的概率降低
  • 总结下来是
    • 优先级反转问题的出现跟自旋锁没有关系
    • 但一旦出现优先级反转问题,自旋锁会让优先级反转问题不容易处理,乃至形成更严重的线程等候问题

atomic和os_unfair_lock

  • OSSpinLock被扔掉后,官方建议运用os_unfair_lock替代;
  • os_unfair_lock其实是互斥锁(参考资料中有说到)
  • 在老版别中,atomic内部也是用自旋锁完结的,但后续也改成互斥锁了

疑问

  1. iOS系统中优先级反转问题是怎样处理的?–参考资料中的苹果官方文档有说到

参考

  • 谈 iOS 的锁
  • 优先级反转那点事儿
  • 不再安全的 OSSpinLock
  • dispatch_semaphore 会形成优先级反转,慎用!
  • Prioritize Work with Quality of Service Classes