news 2026/7/15 6:03:41

【iOS】优先级反转

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【iOS】优先级反转

前言

什么是优先级反转呢?

优先级反转指的是某同步资源被较低优先级线程/进程拥有之后,其他较高优先级的线程/进程竞争未获得该资源,使得较高优先级的进程/线程被阻塞,根据阻塞类型的不同可以分为两类,如下:

类型中文理解核心区别
Bounded Priority Inversion有界优先级反转高优先级线程会被低优先级线程阻塞,但阻塞时间有明确上限
Unbounded Priority Inversion无界优先级反转高优先级线程被阻塞的时间无法确定,理论上可能无限长

优先级反转的后果:

  1. 低优先级的任务比高优先的任务先执行导致任务的错乱。
  2. 可能造成系统崩溃
  3. 产生死锁,低优先级迟迟无法被调度执行

两种类型

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的优先级反转。所以线程所继承的优先级必须是直接或者间接阻塞的线程的最高优先级。

总结

  1. 什么是优先级反转?

优先级反转指的是一个低优先级的任务持有了一个共享资源的锁,而高优先级的任务获取锁的时候被阻塞,此时中间优先级的任务运行并抢占了CPU执行,导致高优先级的任务被反转到中间优先级的任务之后运行。

  1. iOS中如何避免或解决优先级反转问题?
  • 优先级继承:确保持有锁的低优先级任务提升到高优先级任务的级别,知道锁被释放,然后恢复到原来的级别。(记录了锁的持有者的api都可以自动避免优先级的反转,系统会通过提高线程的优先级来解决反转问题,如dispatch_sync)
  • 避免使用信号量机制做线程同步,无法区分是哪个线程持有了信号量
  • 使用合适的锁机制,选择NSlock、NSRecursiceLock等,避免长时间持有锁
  • 避免锁竞争:减少共享资源的使用和锁的力度,避免长时间的锁的竞争
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 6:03:10

<宇将军AI>Claude Opus 4.8:AI代码协作的精准革命

前言 Claude Opus 4.8 的升级并非简单的性能提升,而是针对开发者日常痛点——代码审查、遗留代码解读和需求澄清——进行了精准优化。它通过主动提问、精准定位和承认不确定性,将 AI 从“笼统的建议者”转变为“可靠的协作伙伴”。对于老项目维护者而言&…

作者头像 李华
网站建设 2026/7/15 6:01:14

C++20协程实战:从生成器到异步任务,告别回调地狱

1. 项目概述:为什么我们需要在C里谈论协程?如果你写过网络服务、游戏引擎或者任何需要处理大量并发I/O的程序,肯定对“回调地狱”和“线程切换开销”这两个词深恶痛绝。传统的多线程模型,每个连接一个线程,听起来简单&…

作者头像 李华
网站建设 2026/7/15 6:00:59

米家72LW-PL30/N1A1立柜空调评测:巨省电与大风口技术解析

最近天气越来越热,很多朋友都在考虑给家里添置一台新空调。特别是客厅面积较大的家庭,立柜式空调成了首选。今天要跟大家详细聊聊米家新推出的这款72LW-PL30/N1A1立柜式空调,看看它宣称的"巨省电"和"大风口"到底是不是真…

作者头像 李华
网站建设 2026/7/15 6:00:48

深入理解C++ STL算法库:从核心分类到实战应用

1. 项目概述:为什么我们需要深入理解STL算法库?如果你用C写过一些项目,尤其是涉及到数据处理、业务逻辑或者性能优化的部分,大概率已经和STL的容器打过交道了,比如vector、list、map。容器帮我们把数据组织得井井有条&…

作者头像 李华
网站建设 2026/7/15 5:59:05

C++字体库选型指南:从FreeType到HarfBuzz的实战解析

1. 项目概述:为什么C字体库是开发者的“硬通货”做图形界面、游戏引擎、文档处理,甚至是嵌入式设备上的信息显示,只要涉及到文字,就绕不开字体处理。很多开发者,尤其是刚入行的朋友,常常被字体问题搞得焦头…

作者头像 李华
网站建设 2026/7/15 5:58:07

Docker部署ClickHouse时序数据库

目录 一、拉取 ClickHouse 镜像 二、快速启动(体验版) 三、进入容器 四、测试SQL 五、浏览器访问 六、数据持久化(推荐) 七、设置用户名密码(推荐) 八、使用 Docker Compose(推荐&#…

作者头像 李华