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

这篇具有很好参考价值的文章主要介绍了iOS开发进阶(六):Xcode14 使用信号量造成线程优先级反转问题修复。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

应用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 使用信号量造成线程优先级反转问题修复,iOS,ios,信号量

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

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

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

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

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

二、关于线程优先级反转

优先级反转(Priority 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开发进阶(六):Xcode14 使用信号量造成线程优先级反转问题修复,iOS,ios,信号量

然而,用于 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…,

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

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

然后输入自定义的 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。

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

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

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

  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。文章来源地址https://www.toymoban.com/news/detail-789437.html

到了这里,关于iOS开发进阶(六):Xcode14 使用信号量造成线程优先级反转问题修复的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 信号量Semaphore的概念及其使用

            在操作系统中也经常出现信号量这一概念         Semaphore是并发编程中一个重要的概念/组件         准确来说,Semaphore是一个计数器(变量),描述了” 可用资源的个数 “,描述的是,当前线程是否有” 临界资源可用 “         临界资源表示,多个线程/进程等

    2024年02月14日
    浏览(47)
  • HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核基础-信号量semaphore

    信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数,其值的含义分两种情况: 0,表示该信号量当前不可获取,因此可能

    2024年02月19日
    浏览(47)
  • 【Linux从入门到精通】信号量(信号量的原理与相关操作接口)详解

      本篇文章重点对 信号量的概念,信号量的申请、初始化、释放、销毁等操作进行讲解。同时举例把信号量应用到生产者消费者模型来理解 。希望本篇文章会对你有所帮助。 目录 一、信号量概念 1、1 什么是信号量 1、2 为什么要有信号量 1、3 信号量的PV操作 二、信号量的相

    2024年02月08日
    浏览(48)
  • 【设计模式】C语言使用共享内存和信号量,完美实现生产者与消费者模式

    生产者和消费者模式适用于生产者和消费者之间存在数据交换的场景。在这种模式中,生产者负责生产数据并将其放入缓冲区,而消费者负责从缓冲区中取出数据并进行处理。这种模式的优点是可以实现生产者和消费者之间的解耦,使得它们可以独立地进行操作,从而提高了

    2024年02月03日
    浏览(40)
  • linux信号量

    通过学习linux的信号量,对linux的信号量进行了编程。

    2024年02月10日
    浏览(44)
  • 信号量Semaphore详解

    大家应该都用过 synchronized 加锁,用来保证某个时刻只允许一个线程运行。那么如果控制某个时刻允许指定数量的线程执行,有什么好的办法呢? 答案就是JUC提供的信号量 Semaphore 。 Semaphore (信号量)可以用来限制能同时访问共享资源的线程上限,它内部维护了一个 许

    2024年02月14日
    浏览(53)
  • linux(信号量)

    1.回顾信号量的概念 2.认识信号量对应的操作函数 3.认识一个环形队列 4.结合sem+环形队列写生产者消费者模型 --------------------------------------------------------------------------------------------------------------------------------- 1.回顾信号量的概念  每个人想进放映厅看电影,第一件事就是买票

    2024年02月11日
    浏览(43)
  • uCOSii信号量

    uCOSii 信号量 主要用来测试使用uCOSii“创建信号量,发送信号量,接收信号量,删除信号量”。 学习uCOSii一定要先了解os_cfg.h文件。 信号量管理函数如下: OSSemAccept () 无条件地等待请求一个信号量函数,中断服务子程序只能用OSSemAccept()而不能用OSSemPend(),因为中断服务子程序是不

    2024年02月07日
    浏览(57)
  • 信号量

    信号量(semaphore)和信号只有一字之差,却是不同的概念, 信号量与之前介绍的IPC不同,它是一个计数器,用于实现进程间的互斥于同步 本文参考: Linux 的信号量_linux 信号量_行孤、的博客-CSDN博客 【Linux】Linux的信号量集_Yngz_Miao的博客-CSDN博客 Linux进程间通信(九)——信

    2024年02月12日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包