当前位置: 首页 > news >正文

【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等,避免长时间持有锁
  • 避免锁竞争:减少共享资源的使用和锁的力度,避免长时间的锁的竞争
http://www.cnnetsun.cn/news/3390345.html

相关文章:

  • <宇将军AI>Claude Opus 4.8:AI代码协作的精准革命
  • C++20协程实战:从生成器到异步任务,告别回调地狱
  • 米家72LW-PL30/N1A1立柜空调评测:巨省电与大风口技术解析
  • 深入理解C++ STL算法库:从核心分类到实战应用
  • C++字体库选型指南:从FreeType到HarfBuzz的实战解析
  • Docker部署ClickHouse时序数据库
  • ping命令无效时,我们可以使用工具tcping取而代之
  • C++实现箱线图异常值检测:从算法原理到工程实践
  • ChatGPT Codex与工作模式:AI辅助开发实战指南
  • ChatGPT桌面版:AI工具从网页到工作流的无缝集成变革
  • VC++财务管理系统开发实战:从环境搭建到核心模块实现
  • 突然袭击!Anthropic 发布 Claude 4.8,科技圈彻底炸锅了!
  • 从零到一:配置与解析小程序二维码直达指定页面(实战避坑指南)
  • C++异常处理进阶:从RAII到noexcept的工程实践指南
  • 基于FPGA的车牌识别系统:从算法仿真到硬件部署的实践指南
  • VS Code+Continue构建本地化AI编程环境实战指南
  • GPL开源协议
  • bWAPP漏洞靶场从零搭建指南:三种部署方案与实战入门
  • 无刷直流电机(BLDCM)驱动电路设计与控制策略实战解析
  • 告别GDI卡顿:C#调用DXGI Desktop Duplication API实现高性能桌面采集
  • Unity 2D像素角色动画全流程:从精灵图集导入到性能优化实战
  • IPv6无状态地址自动配置(SLAAC)实战:从RA/RS报文到华为设备配置
  • AMD Ryzen调试工具完全指南:免费开源硬件性能调优神器
  • 遗传算法解决N皇后问题的Python实战与工程细节
  • Voice Changer 实时语音转换实战指南:从部署到深度集成的AI语音处理方案
  • 用AI出现循环并发,请求频繁报错?DMXAPI 聚合平台AI排错工具,给出节流优化方案
  • C++实现最小二乘法多项式拟合:从数学原理到工程实战
  • AR Foundation核心架构解析:从跨平台原理到实战避坑指南
  • 32- 杨逢昌:制造业6S无效整改治理方案——问题三阶过滤标准化体系
  • Python风格轮动回测系统:从量化原理到实盘部署