iOS开发进阶(六):Xcode14 使用信号量造成线程优先级反转问题修复

文章目录

    • 一、前言
    • 二、关于线程优先级反转
    • 三、优先级反转会造成什么后果
    • 四、怎么避免线程优先级反转
    • 五、使用信号量可能会造成线程优先级反转,且无法避免
    • 六、延伸阅读:iOS | Xcode中快速打开终端
      • 6.1 .sh绑定
      • 6.2 执行 `pod install` 脚本
    • 七、延伸阅读:Undefined symbol: _rebind_symbols || symbol(s) not found for architecture arm64
    • 八、延伸阅读: 2 duplicate symbols for architecture arm64
    • 九、延伸阅读:Xcode编译报错:LLDB is likely reading from device memory to resolve symbols.

一、前言

应用Xcode 14.1进行项目编译时,遇到以下错误提示,导致APP线程暂停。

Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions

在这里插入图片描述

以上问题是由于iOS信号量造成线程优先级反转,在并发队列使用信号量会可能会造成线程优先级反转。

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

Thread Performance CheckerXCode14上默认开启的),这个工具会让APP在运行的时候,发现有例如线程优先级反转和非UI工作在主线程上运行等问题的时候,就会在XCode问题导航栏中提示该卡顿风险警告,可以帮助我们在开发初期就能发现并解决隐含的卡顿风险问题;这个不是崩溃,如果不想要,可以在 “Product -> Scheme - > Edit SchemeDiagnostics 中去掉 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所在的目标线程,则无法知道应该提高谁的优先级,也就无法解决反转的问题,如信号量。

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

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

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

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

  3. dispatch_semaphore 不能避免优先级反转的原因:在调用dispatch_semaphore_wait() 的时候,系统不知道哪个线程会调用 dispatch_semaphore_signal()方法,系统无法知道owner信息,无法调整优先级。dispatch_groupsemaphore类似,在调用enter()方法的时候,无法预知谁会leave(),所以系统也不知道owner信息。

六、延伸阅读:iOS | Xcode中快速打开终端

AndroidStudioGoland 等 JetBrains IDEA 一系的代码编辑器中,界面底部有一个 Terminal 选项卡。打开选项卡会创建一个 Terminal,并自动切换到当前项目的根目录下,然后我们就可以在此快速的执行一些命令操作。如下图:

在这里插入图片描述

然而,用于 iOS 开发的 Xcode 中并没有该选项卡,这就很不方便了。接下来讲解如何手动为 Xcode 配置一个 Terminal 的快捷入口。

6.1 .sh绑定

步骤1:新建 xcode-terminal.sh 脚本文件

切换到任意目录,然后新建一个 xcode-terminal.sh 的脚本文件,并编辑其内容。

脚本内容如下:

#!/bin/sh

if [ -n "$XcodeProjectPath" ]; then	
  open -a Terminal "$XcodeProjectPath"/..
else
  open -a Terminal "$XcodeWorkspacePath"/..
fi

另外,.sh 前面的文件名称可以自定义,但是下面步骤2中修改权限时,名称必须一致。

步骤2:修改文件执行权限

打开终端,并在其中执行如下命令:

chmod +x 路径名/.sh文件名

如: chmod +x xcode-terminal.sh

步骤3:脚本命令添加到 Xcode 中

依次打开 : Xcode menu > Behaviors > Edit Behaviors…,

然后点击下图左下角的 + :

在这里插入图片描述

然后输入自定义的 Behavior 名称(对应上图中的 2),并指定一个快捷键(对应上图中的3)。

然后勾选上图右侧的 Run(对应上图中的4), 并双击 Run 右侧的下拉框(对应上图中的 5 ),指定该 Behavior 对应的脚本文件——也就是刚才创建的 xcode-terminal.sh。

至此,配置完成。在 Xcode 编辑器中,按下自定义的快捷键就可以调出终端了。

6.2 执行 pod install 脚本

脚本内容如下:

#!/bin/sh
# 改脚本用于Xcode 执行快捷键执行 pod install 

path=""
if [ -n "$XcodeProjectPath" ]; then
    path=$XcodeProjectPath
else
    path=$XcodeWorkspacePath	
fi
# 执行 AppleScript 打开 Terminal 进行 podinstall
osascript <<EOF
    tell application "Terminal"
        activate
        do script with command "cd \"$path\"/..;pod install"
    end tell
EOF

总结
任意需求都可以通过脚本实现,然后可以将其关联到 Xcode 的 behavious 中,并为其关联快捷键。

七、延伸阅读:Undefined symbol: _rebind_symbols || symbol(s) not found for architecture arm64

xcode 14 给出如下错误提示信息:

Undefined symbols for architecture arm64:
  "_rebind_symbols", referenced from:
      ___32+[RCTReconnectingWebSocket load]_block_invoke in libReact-RCTWebSocket.a(RCTReconnectingWebSocket.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决方案:

  1. 清理Xcode缓存
rm -rf ~/Library/Developer/Xcode/DerivedData/

2)清理CocoaPods缓存

切换到项目ios目录下,执行以下命令。

rm -rf "${HOME}/Library/Caches/CocoaPods" 
rm -rf "`pwd`/Pods/" 
pod update

若执行 pod update 命令报错,则执行以下命令:

cd ..
pod install --project-directory=ios
  1. 最后将Build Active Architectures Only 设置为NO

八、延伸阅读: 2 duplicate symbols for architecture arm64

编译阶段,错误提示信息如下:

duplicate symbol '_OBJC_CLASS_$_Orientation' in:
    /Users/ccms-m-03/Library/Developer/Xcode/DerivedData/mrcs-erictiduzoziyxgpkngocqfejvjq/Build/Intermediates.noindex/mrcs.build/Debug-iphoneos/mrcs.build/Objects-normal/arm64/Orientation.o
    /Users/ccms-m-03/Library/Developer/Xcode/DerivedData/mrcs-erictiduzoziyxgpkngocqfejvjq/Build/Products/Debug-iphoneos/react-native-orientation/libreact-native-orientation.a(Orientation.o)
duplicate symbol '_OBJC_METACLASS_$_Orientation' in:
    /Users/ccms-m-03/Library/Developer/Xcode/DerivedData/mrcs-erictiduzoziyxgpkngocqfejvjq/Build/Intermediates.noindex/mrcs.build/Debug-iphoneos/mrcs.build/Objects-normal/arm64/Orientation.o
    /Users/ccms-m-03/Library/Developer/Xcode/DerivedData/mrcs-erictiduzoziyxgpkngocqfejvjq/Build/Products/Debug-iphoneos/react-native-orientation/libreact-native-orientation.a(Orientation.o)
ld: 2 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决方案:根据提示搜索重复文件Orientation。

若存在重复文件,则删掉一个。

在这里插入图片描述

此外,也可以通过以下步骤检查:

  1. 首先排查是否有名字重复的文件。(查看下自己的项目中创立的文件名和引入的第三方文件名是否重复)。

  2. 检查是否在#import头文件的时候,不小心把.h写成了.m(可以全局搜索是否是这个问题).

  3. 仔细在报错的类中找下是否有重复添加 .h头文件。

九、延伸阅读:Xcode编译报错:LLDB is likely reading from device memory to resolve symbols.

ios应用在本地热部署启动过程中,控制台给出以下提示信息:

Launching “**” is taking longer than expected. Do you want to continue to wait?
LLDB is likely reading from device memory to resolve symbols.

问题分析:
大概意思是编译时间会比预期的要长,是否继续等待。主要是新操作系统和Xcode旧版的架构不匹配造成的。

解决方案:
通过访达,“前往文件夹”功能输入~/Library/Developer/Xcode/,进入iOS DeviceSupport目录,删除该真机对应的架构文件(比如iOS15.1,就删除iOS15.1的架构文件),退出Xcode,拔掉手机,重新连接打开Xcode,解决。

如果上面方案不行,选择Xcode->Window->Devices and Simulators(command+shift+2),鼠标右键点击真机设备,选择Unpair Device。解除信任,然后重新拔插手机,重新信任,重启Xcode。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/317660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL性能测试及调优中的死锁处理方法

以下从死锁检测、死锁避免、死锁解决3个方面来探讨如何对MySQL死锁问题进行性能调优。 死锁检测 通过SQL语句查询锁表相关信息&#xff1a; &#xff08;1&#xff09;查询表打开情况 SHOW OPEN TABLES WHERE IN_USE> 01 &#xff08;2&#xff09;查询锁情况列表 SEL…

达梦数据实时同步软件DMHS介绍和原理

1、产品介绍 达梦数据实时同步软件&#xff08;以下简称 DMHS&#xff09;是支持异构环境的高性能、高可靠、高可扩展数据库实时同步复制系统。该产品采用基于日志的结构化数据复制技术&#xff0c;不依赖主机上源数据库的触发器或者规则&#xff0c;对主机源数据库系统几乎无影…

计算机msvcp140.dll丢失如何解决,分享3个简单有效的方法

在计算机系统运行过程中&#xff0c;用户有时会遇到一个常见的错误提示——msvcp140.dll文件缺失&#xff0c;这一问题的发生往往会导致部分软件无法正常启动或运行。“针对计算机系统中出现的msvcp140.dll缺失问题&#xff0c;小编将详尽阐述并探讨5种有效的解决策略。每一种方…

Linux的SSH服务

一.SSH服务简介 1.什么是SSH SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c;主要用来实现字符界面的远程登录、远程复制等功能。SSH 协议对通信双方的数据传输进行了加密处理&#xff0c;其中包括用户登录时输入的用户口令&#xff0c;SSH 为建立在应…

java大学生宿舍共享厨房系统宿舍自习室宿舍洗衣房系统源码包含技术文档

主要功能&#xff1a;学生可注册登录&#xff0c;预约自己宿舍楼栋的共享厨房和评价&#xff0c;也可以使用该楼栋的洗衣房&#xff0c;查看洗衣机吹风机的使用情况和报修&#xff0c;还可以进入该楼栋自习室打卡和评价。管理员可管理所有的学生和宿管&#xff0c;分配宿舍&…

【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】

前言 大家好吖&#xff0c;欢迎来到 YY 滴C考前速过系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《…

【MATLAB源码-第110期】基于matlab的哈里斯鹰优化算发(HHO)无人机三维路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 哈里斯鹰优化算法&#xff08;Harris Hawk Optimization, HHO&#xff09;是一种受自然界捕食行为启发的优化算法。它基于哈里斯鹰的捕猎策略和行为模式&#xff0c;主要用于解决各种复杂的优化问题。这个算法的核心特征在于…

神经辐射场(NeRFs)的研究进展

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;神经辐射场&#xff08;NeRFs&#xff09;的研究进展1、研究背景2、方法发展3、相关方法3.1、Pixel NeRF3.2、RegNeRF3.3、Mip-Ne…

全链路追踪关键技术-TraceId、SpanId生成规则

链路追踪的traceid原理梳理 如何追踪微服务调用&#xff1f; ● traceId&#xff0c;用于标识某一次具体的请求ID。当用户的请求进入系统后&#xff0c;会在RPC调用网络的第一层生成一个全局唯一的traceId&#xff0c;并且会随着每一层的RPC调用&#xff0c;不断往后传递&…

FFmpeg 的使用与Docker安装流媒体服务器

本文阐述的均为命令行的使用方式&#xff0c;并不牵扯FFmpeg 的 C音视频开发内容&#xff0c;补充一句&#xff0c;C的资料真的少&#xff0c;能把C学好的人&#xff0c;我真的是觉得巨佬。 我主要是使用FFmpeg 推流方面的知识&#xff0c;案例大都是靠近这方面。 一、FFmpeg…

leetcode 125. 验证回文串

题目&#xff1a; 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &…

【开源项目】深圳智慧城市~超经典CIM/BIM数字孪生可视化项目

飞渡科技数字孪生城市运行管理平台&#xff0c;以数字孪生为核心底层系统&#xff0c;将实景三维、大数据、云计算、人工智能等新一代技术&#xff0c;与城市管理服务相融合&#xff0c;构建高速率、高可靠和低延时的应用场景&#xff0c;打造全程全时、全模式全响应的数字孪生…

跨境电商必备:好用的邮箱推荐与实用指南

对于跨境电商企业而言&#xff0c;一封精炼、高效的邮件往往成为与国外买家或供应商沟通的利器。因此挑选一个得心应手的邮箱供应商&#xff0c;对于确保业务畅通无阻至关重要。本文将深入浅出地探讨跨境电商如何挑选邮箱&#xff0c;并推荐一些备受青睐的邮箱服务供应商。 一、…

LeNet-5(fashion-mnist)

文章目录 前言LeNet模型训练 前言 LeNet是最早发布的卷积神经网络之一。该模型被提出用于识别图像中的手写数字。 LeNet LeNet-5由以下两个部分组成 卷积编码器&#xff08;2&#xff09;全连接层&#xff08;3&#xff09; 卷积块由一个卷积层、一个sigmoid激活函数和一个…

GitHub项目推荐-incubator

项目地址 Github地址&#xff1a;GitHub - apache/incubator-anser 官网&#xff1a;Apache Answer | Free Open-source Q&A Platform 项目简述 这是Apache的一个开源在线论坛&#xff0c;也可以部署成为一个自有的QA知识库。项目主要使用了Go和Typescript来开发&#…

微服务治理:微服务断路器(微服务故障隔离模式)详解

微服务断路器是一种设计模式&#xff0c;可以保护系统免于级联故障&#xff0c;通过限制对故障服务的调用来实现。它的工作原理类似于电气断路器&#xff1a;当服务遇到问题时&#xff0c;它会切断请求流&#xff0c;使其有机会恢复&#xff0c;并防止其他服务被压垮。 工作原…

短视频抖音文案策划创作运营手册资料大全

【干货资料持续更新&#xff0c;以防走丢】 短视频抖音文案策划创作运营手册资料大全 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 抖音运营资料合集&#xff08;完整资料包含以下内容&#xff09; 目录 制作短视频的四部曲 主题 主题是短视频脚本的基调…

(学习日记)2024.01.13:一份关于自行车定位的调研 2

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

Springboot读取配置文件

多种配置文件格式 springboot项目中不同配置文件的优先加载顺序 为&#xff1a;properties> yml >yaml>自定义核心类配置 自定义配置文件的加载 一般系统会加载默认的application.properties或者application.yml,但如果使用自定义配置文件&#xff0c;可使用下面方…

计算机毕业设计-----SpringBoot招聘网站项目

项目介绍 SpringBoot招聘网站项目。主要功能说明&#xff1a; 管理员登录,简历管理,问答管理,职位管理,用户管理,职位申请进度更新,查看简历等功能。 用户角色包含以下功能&#xff1a;用户首页,登录注册,职位查看,职位详情,投递简历,查看我的申请,管理个人简历,附件简历管理…