【iOS】优先级反转

📅 2026/7/15 6:03:50
【iOS】优先级反转
前言什么是优先级反转呢优先级反转指的是某同步资源被较低优先级线程/进程拥有之后其他较高优先级的线程/进程竞争未获得该资源使得较高优先级的进程/线程被阻塞根据阻塞类型的不同可以分为两类如下类型中文理解核心区别Bounded Priority Inversion有界优先级反转高优先级线程会被低优先级线程阻塞但阻塞时间有明确上限Unbounded Priority Inversion无界优先级反转高优先级线程被阻塞的时间无法确定理论上可能无限长优先级反转的后果低优先级的任务比高优先的任务先执行导致任务的错乱。可能造成系统崩溃产生死锁低优先级迟迟无法被调度执行两种类型Bounded Priority Inversion高优先级线程虽然被低优先级线程阻塞了但这个阻塞时间是可预测、可控制、有上限的。阻塞时间取决于低优先级任务在临界区的时间即持有锁的时间。所以只要低优先级的线程一直持有锁那么高优先级的线程就会一致被阻塞低优先级的任务就会排在高优先级人物的前面优先级被反转。只要低优先级的线程能够运行并释放锁那么优先级反转就会结束。Unbounded priority inversion高优先级线程等待低优先级线程释放资源但是低优先级线程可能长期不会得到执行的机会导致高优先级线程等待的时间没有明确上限。但是实际实践中我们会发现中间优先级线程不会一致抢占CPU这是因为普通用户态线程默认不会严格抢占优先级只是一个建议而不是强制的。线程的实际调度还受到系统负载、CPU核心数、线程创建顺序等的影响。解决办法目前解决无界优先级反转有两种方法优先权极限优先级继承优先权极限系统将每一个临界资源与一个极限优先权相关联当1个任务进入临界区时系统便会将这个极限优先权传递给这个任务使得这个任务的优先级最高当任务退出临界区之后系统将其优先权恢复正常。这个极限优先权的值是由所有需要该临界资源的任务的最大优先级来决定的。优先级继承大致的原理就是当高优先级任务在尝试获取锁的时候如果该锁正好被低优先级任务持有此时会临时的将高优先级线程的优先级转移给拥有锁的低优先级线程使得低优先级线程能更快的执行并释放同步资源释放完资源之后恢复为原来的优先级。这两种方法只能阻止无界优先级反转而不能阻止有界优先级反转。有界优先级反转必须等待低优先级线程执行完毕以后才能执行这个反转是无法避免的我们还需要注意的是优先级继承是可以传递的举个例子来说当线程1阻塞在被线程2持有的资源上而线程2又被阻塞在线程3持有的资源上瑞国线程1的优先级高于线程2和线程3的优先级那么线程3必须通过线程2继承线程1的优先级。不然如果有一个线程4的优先级高于线程2和线程3但是小于线程1的优先级就会抢占线程3的执行引发相对于线程1的优先级反转。所以线程所继承的优先级必须是直接或者间接阻塞的线程的最高优先级。总结什么是优先级反转优先级反转指的是一个低优先级的任务持有了一个共享资源的锁而高优先级的任务获取锁的时候被阻塞此时中间优先级的任务运行并抢占了CPU执行导致高优先级的任务被反转到中间优先级的任务之后运行。iOS中如何避免或解决优先级反转问题优先级继承确保持有锁的低优先级任务提升到高优先级任务的级别知道锁被释放然后恢复到原来的级别。记录了锁的持有者的api都可以自动避免优先级的反转系统会通过提高线程的优先级来解决反转问题如dispatch_sync避免使用信号量机制做线程同步无法区分是哪个线程持有了信号量使用合适的锁机制选择NSlock、NSRecursiceLock等避免长时间持有锁避免锁竞争减少共享资源的使用和锁的力度避免长时间的锁的竞争