在并发队列使用信号量会可能会造成线程优先级反转

一、在iOS16 & XCode14上遇到 - 使用信号量造成线程优先级反转问题 提醒

经过查询资料,发现是在XCode14上增加了工具,比如 :

Thread Performance Checker (XCode14上默认开启的),这个工具会让APP在运行的时候,发现有例如线程优先级反转和非UI工作在主线程上运行等问题的时候,就会在XCode问题导航栏中提示该卡顿风险警告,可以帮助我们在开发初期就能发现并解决隐含的卡顿风险问题;这个不是崩溃,如果不想要,可以在 “Product -> Scheme - > Edit Scheme 的 Diagnostics 中去掉 Thread Performance Checker勾选”

XCode14还有其他一些新增加的工具类,可参考 iOS卡顿检测

二、关于线程优先级反转

优先级反转(Poiority Inversion) 指高优先级任务需要等待低优先级任务执行完成才能继续执行,这种情况下优先级被反转了。

举例:有三个线程分别为:A、B、C。优先级A > B > C,线程A和B处于挂起状态,等待某一事件发生,线程C正在运行,此时任务C开始使用共享资源Source。在使用Source时,线程A等待事件到来,线程A转为就绪态,因为线程A优先级比线程C高,所以线程A会立即执行。当线程A要使用共享资源Source时,由于共享资源Source正在被线程C使用,因此线程A被挂起,线程C开始运行。如果此时中等优先级线程B等待事件到来,则线程B转为就绪态。由于线程B优先级比线程C高,因此线程B开始运行,直到其运行完毕,线程C才开始运行。直到线程C释放共享资源Source后,线程A才得以执行。在这种情况下,优先级发生了翻转,线程B先于线程A运行。

三、优先级反转会造成什么后果

低优先级的任务比高优先级的任务先执行,导致任务的错乱,逻辑错乱;

可能造成系统崩溃;

死锁;优先级低的线程迟迟得不到调度,具有高优先级的线程不能执行,死锁;

四、怎么避免线程优先级反转

如果当前线程因等待某线程上正在进行的 操作如(block1)而受阻,而系统知道block1的所在的目标线程,系统会通过提高相关线程的优先级来解决优先级反转的问题 (如线程A在尝试获取共享资源而被挂起的期间内,将线程C的优先级提升到同线程A的优先级,等线程C处理结束,降回原优先级,这样能防止C被B抢占)。如果不知道block1所在的目标线程,则无法知道应该提高谁的优先级,也就无法解决反转的问题,如信号量。

五、使用信号量可能会造成线程优先级反转,且无法避免

QoS (Quality of Service),用来指示某任务或者队列的运行优先级;

1、记录了持有者的api都可以自动避免优先级反转,系统会通过提高相关线程的优先级来解决优先级反转的问题,如 dispatch_sync, 如果系统不知道持有者所在的线程,则无法知道应该提高谁的优先级,也就无法解决反转问题。

2、慎用dispatch_semaphore 做线程同步

dispatch_semaphore 容易造成优先级反转,因为api没有记录是哪个线程持有了信号量,所以有高优先级的线程在等待锁的时候,内核无法知道该提高那个线程的优先级(QoS);

3、dispatch_semaphore 不能避免优先级反转的原因

在调用dispatch_semaphore_wait() 的时候,系统不知道哪个线程会调用 dispatch_semaphore_signal()方法,系统无法知道owner信息,无法调整优先级。dispatch_group 和semaphore类似,在调用enter()方法的时候,无法预知谁会leave(),所以系统也不知道owner信息

参考资料:

优先级反转

优先级反转那些事儿

Diagnosing Performance issues early

dispatch_semaphore 会造成优先级反转,慎用!

作者:京东零售 孙巧巧

来源:京东云开发者社区 转载请注明来源

iOS信号量造成线程优先级反转的更多相关文章

  1. 优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】

    RTOS中很经典的问题.就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题.这里模拟这种情况. 下面的实验模拟了优先级反转的情况: 先定义三个线程: //优先级反转实验 rt_se ...

  2. 【C# 线程】优先级反转与优先级继承

    什么是优先级反转(翻转)优先级反转,是指在使用信号量时,可能会出现的这样一种不合理的现象,即:    高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度.但其他中等优先级的任务却能抢到CP ...

  3. ucos互斥信号量解决优先级反转问题

    在可剥夺性的内核中,当任务以独占方式使用共享资源的时候,会出现低优先级任务高于高优先级任务运行的情况,这种情况叫做优先级反转,对于实时操作系统而言,这是一场灾难,下面我们来说说优先级反转的典型环境. ...

  4. ucos之互斥信号量及优先级反转

    在ucos常使用共享资源来作为任务之间的通信方式,其中有:消息队列,信号量,邮箱,事件.信号量中又分二值信号,多值信号,互斥信号.这次主要讲二值信号与互斥信号之间区别和使用. 首先了解一下ucos的任 ...

  5. iOS开发系列-线程同步技术

    概述 多线程的本质就是CPU轮流随机分配给每条线程时间片资源执行任务,看起来多条线程同时执行任务. 多条线程同时访问同一块资源,比如操作同一个对象.统一变量.同一个文件,就会引发数据错乱和数据安全的问 ...

  6. iOS信号量的使用

    Core Audio render thread and thread signalling up vote2down votefavorite   Does iOS have any kind of ...

  7. iOS/OS X线程安全的基础知识

    处理多并发和可重入性问题,是每个库发展过程中面临的比较困难的挑战之一.在Parse平台上,我们尽最大的努力保证你在使用我的SDKs时所做的操作都是线程安全的,保证不会出现性能问题. 在这篇文章中我们将 ...

  8. Cocos2dx中线程优先级

    Cocos2dx中线程优先级问题 不论是ios还是android,遇到耗时的任务都要另起线程处理,否则程序不能及时用户的反馈.游戏中如果一圈循环不能在1/frameRate(帧率是30则1/30)秒内 ...

  9. Linux同步机制 - 基本概念(死锁,活锁,饿死,优先级反转,护航现象)

    死锁(deadlock) 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...

  10. 线程调度的问题:Lock Convoy(锁封护)与Priority Inversion(优先级反转)

    Lock Convoy(锁封护) [1]Lock Convoy是在多线程并发环境下由于锁的使用而引起的性能退化问题.当多个相同优先级的线程频繁地争抢同一个锁时可能会引起lock convoy问题,一般 ...

随机推荐

  1. Linux学习环境搭建(VMware虚拟机安装Linux)

    企业现状 目前绝大多数企业运维人员的工作环境都是Windows下通过SSH工具(如XShell等)远程连接千百里外的服务器进行管理和维护的. 而且学Linux运维,99.9%知识与硬件无关,用虚拟机足 ...

  2. 创建python虚拟环境并打包python文件

    前言 当需要为一个离线环境部署python应用时,离线环境可能缺少各种python环境,有docker的话可以用docker,没有docker可以用pyinstaller打包成二进制文件.pyinst ...

  3. 解决win10/ubuntu端口占用问题

    win10解决方案 首先打开cmd命令行 命令行里输入 netstat -ano|findstr 被占用端口号 然后可以看到占用该端口号的pid 输入taskkill -f -pid pid号即可 u ...

  4. Web通用漏洞--SSRF

    Web通用漏洞--SSRF 漏洞简介 SSRF(Server-Side Request Forgery:服务器端请求伪造) 一种由攻击者构造形成由服务端发起请求的一个安全漏洞; 一般情况下,SSRF攻 ...

  5. 从壹开始前后端开发【.Net6+Vue3】

    项目名称:KeepGoing(继续前进) 1.1介绍 工作后,学习的脚步一直停停走走,希望可以以此项目为基础,可以不断的迫使自己不断的学习以及成长 将以Girvs框架为基础,从壹开始二次开发一个前后端 ...

  6. Android 项目移植后运行黑屏

    在做Android项目的移植过程中,即把名为a的代码和样式全部复制到b项目后,只是对a项目内多余代码删除和修改包名,最后替换完后,点击=>运行,运行成功,但是演示机显示黑屏,看log也没有报错. ...

  7. 弹性数据库连接池探活策略调研(一)——HikariCP

    调研背景: 数据库连接建立是比较昂贵的操作(至少对于 OLTP),不仅要建立 TCP 连接外还需要进行连接鉴权操作,所以客户端通常会把数据库连接保存到连接池中进行复用.连接池维护到弹性数据库(JED) ...

  8. SpringBoot + 自定义注解,实现用户操作日志(支持SpEL表达式)

    背景 一个成熟的系统,都会针对一些关键的操作,去创建用户操作日志. 比如: XX人创建了一条订单,订单号:XXXXXXXXX 因为操作人或者订单号是动态的,所以有些开发人员,不知道获取,就将这种操作日 ...

  9. 小知识:OCI实例的私钥文件权限

    在OCI上创建新的实例时,会提示你保存私钥用于连接,而且该界面不会再次显示,所以一定要保存好这个私钥. 实例创建完成后,当使用保存的私钥进行连接时,却发现由于私钥文件的权限问题无法连接,查看当前私钥文 ...

  10. Jenkins持续集成入门到精通(入门篇)

    1. 什么是持续集成 持续集成(Continuous integration,简称CI)指的是频繁将代码集成到主干.它的目的,就是让产品可以快速迭代,同时保持高质量.核心措施,代码集成到主干之前,必须 ...