iOS - 自旋锁
在 Objective-C 运行时中大量使用自旋锁,主要有以下几个原因:
1. 性能考虑
上下文切换成本
// 自旋锁实现
static ALWAYS_INLINE void OSSpinLockLock(volatile OSSpinLock *lock) {do {while (lock->value != 0) {__asm__ volatile ("pause"); // 不释放CPU,继续尝试}} while (!OSAtomicCompareAndSwap32(0, 1, &lock->value));
}// 相比互斥锁的实现
pthread_mutex_lock(&mutex); // 可能导致线程休眠和上下文切换
// ...
pthread_mutex_unlock(&mutex);
优势:
- 避免了线程上下文切换的开销
- 适合短期持有的场景
- 在多核处理器上效率更高
2. 使用场景特点
短暂的临界区
// 属性访问的典型场景
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {if (!atomic) return *((id *)((char *)self + offset));spinlock_t& slotlock = PropertyLocks[GOODHASH(offset)];slotlock.lock(); // 持锁时间极短id value = *((id *)((char *)self + offset));slotlock.unlock();return value;
}
特点:
- 锁的持有时间非常短
- 竞争不激烈
- 代码路径简单
3. 内存效率
结构简单
typedef struct {volatile int32_t value; // 仅需要一个32位整数
} OSSpinLock;// 相比互斥锁的复杂结构
struct pthread_mutex_t {// ... 更复杂的内部结构// 包含条件变量、等待队列等
};
优势:
- 内存占用小
- 缓存友好
- 初始化成本低
4. 适用的情况
理想场景
// 引用计数操作
inline bool objc_object::sidetable_tryRetain() {SideTable& table = SideTables()[this];bool result = false;table.lock(); // 快速的加锁解锁// 简单的引用计数操作table.unlock();return result;
}
最佳实践:
- 临界区执行时间短
- 线程等待时间短
- CPU资源充足
5. 潜在问题
优先级反转
// 可能出现的问题场景
while (lock->value != 0) {// 如果持有锁的是低优先级线程// 而等待的是高优先级线程// 可能导致优先级反转__asm__ volatile ("pause");
}
解决方案:
- iOS 10 后系统更多使用 os_unfair_lock
- 对于复杂场景使用互斥锁
- 需要考虑优先级时使用其他锁机制
6. 使用建议
适合使用自旋锁的场景
// 1. 简单的原子操作
atomic_property.lock();
value = _property;
atomic_property.unlock();// 2. 快速的引用计数操作
spinlock.lock();
refCount++;
spinlock.unlock();
不适合使用自旋锁的场景
// 1. 复杂的操作
lock.lock();
[self complexOperation]; // 耗时操作
lock.unlock();// 2. 可能阻塞的操作
lock.lock();
[self operationMayBlock]; // 可能阻塞
lock.unlock();
7. 总结
自旋锁在 Objective-C 运行时中的广泛使用是基于以下考虑:
- 性能优化:避免上下文切换
- 场景匹配:适合短期、快速的操作
- 资源效率:内存占用小,初始化快
- 实现简单:容易维护和调试
- 硬件友好:在现代多核处理器上表现良好
但需要注意:
- 不适合长时间持有
- 要考虑优先级反转问题
- iOS 10 后推荐使用 os_unfair_lock
- 复杂场景应考虑其他锁机制
相关文章:
iOS - 自旋锁
在 Objective-C 运行时中大量使用自旋锁,主要有以下几个原因: 1. 性能考虑 上下文切换成本 // 自旋锁实现 static ALWAYS_INLINE void OSSpinLockLock(volatile OSSpinLock *lock) {do {while (lock->value ! 0) {__asm__ volatile ("pause&q…...
域名备案页面模板
域名备案模板,首页底下正中央位置需要有备案号。 主要是给不太擅长于前端样式的人提供一个备案模板,直接把这个H5放到nginx的index.html就可以访问了 <html><body><div class"login-container"><h2>登录</h2>&…...
【socketioxide和axum集成-实现websocket实时通信-Rust点滴】
socketioxide的axum集成 启动socketio依靠examle里的layer一. 使用可变State依靠axum里的example二.提取client,IP1. 非代理,tcp,socket对方地址2.代理情况下socket.req_parts. 三. axum的handle中使用emit发送消息.1. io,存入State解决.2.把io存入初始设定作为唯一单例3.http-…...
计算机网络(第8版)第3章--PPP课后习题
【3-09】 一 个PPP 帧的数据部分(用十六进制写出)是7 D 5EFE 277D 5D7D 5D657D 5E。 试问真正的数据是什么(用十六进制写出)? 解答:把由转义符7D开始的2字节序列用下画线标出: 7D 5E FE 27 7D 5D 7D 5D 65 7D 5E 7D 5E应当还原成为7E。 7D5D 应…...
通过Android Studio修改第三方jar包并重新生成jar包
最近接手了来自公司其他同事的一个Unity项目,里面有一个封装的jar包要改动一下,无奈关于这个jar包的原工程文件丢失了,于是自己动手来修改下jar包,并做下记录。 一、导入第三方jar包 1、新建项目EditJarDemo(项目名随便取) 2、新建libs文件夹,把你要修改的third.jar 复制…...
Rabbitmq 业务异常与未手动确认场景及解决方案
消费端消费异常,业务异常 与 未手动确认是不是一个场景,因为执行完业务逻辑,再确认。解决方案就一个,就是重试一定次数,然后加入死信队列。还有就是消费重新放入队列,然后重新投递给其他消费者,…...
3D机器视觉的类型、应用和未来趋势
3D相机正在推动机器视觉市场的增长。很多制造企业开始转向自动化3D料箱拣选,专注于使用3D视觉和人工智能等先进技术来简化操作并减少开支。 预计3D相机将在未来五年内推动全球机器视觉市场,这得益于移动机器人和机器人拣选的强劲增长。到 2028 年&#…...
LabVIEW在反馈控制时如何解决带约束的控制问题
在LabVIEW中,解决带约束的反馈控制问题通常需要使用先进的控制算法或特定的方法来满足约束条件,同时保证控制系统的性能和稳定性。以下是解决这类问题的一些常用方法和步骤: 1. 定义控制问题及约束条件 确定被控对象的动态特性(…...
PHP 在 2025 年的现状与展望
PHP 在 2025 年依然强劲,继续为超过 77% 使用已知服务器端编程语言的网站提供动力。这并非仅仅依靠遗留代码,像 WordPress、Shopify 和 Laravel 这样的主流平台持续推动 PHP 的发展,使其保持着 актуальность 并不断进化。 为什么…...
QT c++ 自定义按钮类 加载图片 美化按钮
如果你有需要利用图片美化按钮的情况,本文能帮助你。 鼠标左键按下按钮和松开,按钮显示不同的图片。 1.按钮类 //因为此类比较简单,1个头文件搞定,没有cpp文件 #ifndef CUSTOMBUTTON_H #define CUSTOMBUTTON_H #include <Q…...
夯实前端基础之HTML篇
知识点概览 HTML部分 1. DOM和BOM有什么区别? DOM(Document Object Model) 当网页被加载时,浏览器会创建页面的对象文档模型,HTML DOM 模型被结构化为对象树 用途: 主要用于网页内容的动态修改和交互&…...
pytest 参数介绍
命令行参数描述常见使用案例-v / --verbose显示每个测试用例的详细信息,包括测试名称和状态pytest -v-s / --captureno禁用输出捕获,允许 print() 输出显示pytest -s-q / --quiet安静模式,减少输出,仅显示每个测试的通过/失败结果…...
蓝桥杯训练
1对于一个字母矩阵,我们称矩阵中的一个递增序列是指在矩阵中找到两个字母,它们在同一行,同一列,或者在同一 45 度的斜线上,这两个字母从左向右看、或者从上向下看是递增的。 例如,如下矩阵中 LANN QIAO有…...
maven的简单介绍
目录 1、maven简介2、maven 的主要特点3、maven的下载与安装4、修改配置文件5、私服(拓展) 1、maven简介 Maven 是一个广泛使用的项目管理和构建工具,主要应用于 Java 项目。Maven 由 Apache 软件基金会开发和维护,它提供了一种简洁且一致的方法来构建、…...
超完整Docker学习记录,Docker常用命令详解
前言 关于国内拉取不到docker镜像的问题,可以利用Github Action将需要的镜像转存到阿里云私有仓库,然后再通过阿里云私有仓库去拉取就可以了。 参考项目地址:使用Github Action将国外的Docker镜像转存到阿里云私有仓库 一、Docker简介 Do…...
Kafka优势剖析-消费者组、并行消费
目录 1. 消费者组(Consumer Group) 1.1 什么是消费者组? 1.2 消费者组的工作原理 1.3 消费者组的优势 2. 并行消费(Parallel Consumption) 2.1 什么是并行消费? 2.2 并行消费的工作原理 2.3 并行消…...
MATLAB语言的多线程编程
MATLAB语言的多线程编程 引言 随着计算机技术的不断发展,尤其是在大数据和高性能计算领域,多线程编程逐渐成为一种重要的编程范式。MATLAB作为一种广泛应用于科学计算和工程模拟的高级编程语言,其强大的数学计算功能和丰富的工具箱…...
强化学习入门
RL学习路径 理解DQN原理 理解 标准版的策略梯度算法(Vanilla Policy Gradient) 模仿学习实践 Actor-Critic原理 从大模型机器人到imitation Learning与diffusion policy、ACT(Action Chunking with Transformers)的关系 大模型与机器人 tmp: 强化学习中的优势函数&#…...
Unity 2d描边基于SpriteRender,高性能的描边解决方案
目标 以Unity默认渲染管线为例,打造不需要图片内边距,描边平滑,高性能的描边解决方案 前言 在2d游戏中经常需要给2d对象添加描边,来突出强调2d对象 当你去网上查找2d描边shader,移植到项目里面,大概率会…...
2025第2周 | JavaScript中的Symbol
目录 1. Symbol是个什么东东?1.1 语法 2. 为什么需要Symbol?3. 怎么使用Symbol?3.1 定义对象字面量3.2 新增对象属性3.3 使用 Object.defineProperty方式3.4 遍历 4. 静态方法4.1 Symbol.for(key)4.2 Symbol.keyFor(symbol) 2025,做想做的事࿰…...
Unity学习之UGUI进阶
一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 (1)常用事件接口 (2)不常用事件接口 3、使用事件监听接口 &#…...
IT面试求职系列主题-Jenkins
想成功求职,必要的IT技能一样不能少,先说说Jenkins的必会知识吧。 1) 什么是Jenkins Jenkins 是一个用 Java 编写的开源持续集成工具。它跟踪版本控制系统,并在发生更改时启动和监视构建系统。 2)Maven、Ant和Jenkins有什么区别…...
Allure 集成 pytest
Allure 是一个强大的测试报告工具,与 pytest 集成可以生成详细的测试报告,包括测试步骤、测试数据、截图、错误堆栈等。 1. 安装 Allure 和相关依赖 安装 pytest-allure-adaptor 插件: pip install allure-pytest确保本地已安装 Allure 工具。…...
Redis高频知识点
Redis 目录 1 Redis是AP的还是CP的?2 介绍一下Redis的集群方案?3 什么是Redis的数据分片?4 Redis为什么这么快?5 Redis 的事务机制是怎样的?7 Redis的持久化机制是怎样的?8 Redis 的过期策略是怎么样的&a…...
【电子通识】PWM驱动让有刷直流电机恒流工作
电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作,其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时,电机会怎样工作呢࿱…...
PyMysql 02|(包含项目实战)数据库工具类封装
目录 七、数据库工具类封装 1、封装的目的 2、设计数据库工具类 3、实现类方法 1️⃣获取、关闭连接 2️⃣查询一条记录 3️⃣增删改数据 4️⃣完整封装代码实现 七、数据库工具类封装 1、封装的目的 将常用的数据库操作,封装到一个方法。 后续再操作数据…...
Pixel 6a手机提示无法连接移动网络,打电话失败!
1、开启VoLTE 2、如果没有,下载shizuku和PixelIMS应用。 shizuke Releases RikkaApps/Shizuku GitHub PixellMS Release v1.2.8 kyujin-cho/pixel-volte-patch GitHub 3、安装shizuke启动,开通root可以直接点击下面的启动,如果没有就…...
ubuntu20.04 在线安装postgresql 扩展postgis
基础配置 /etc/apt/sources.list # 添加pg官方基础配置deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main# 添加ubuntu官方依赖(防止下载依赖错误)deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse de…...
fitz获取pdf内容
1.获取pdf单页,及所有内容 import fitz # PyMuPDF# 打开 PDF 文件 pdf_path r"/data2/ljsang/0106/0725_Self-organization-of-plasticity-and-specialization-in-a-primi_2022_Cell-Syst.pdfπσΣ╕╖σσ║Θ║∩╝Φ╛τ▒│σ¡τ╛π.pdf" d…...
LabVIEW软件Bug的定义与修改
在LabVIEW软件开发过程中,bug(程序错误或缺陷)指的是程序中导致不符合预期行为的任何问题。Bug可能是由于编码错误、逻辑漏洞、硬件兼容性问题、系统资源限制等因素引起的。它可能会导致程序崩溃、功能无法正常执行或输出结果不符合预期。理解…...
Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开
element文档链接: https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注:Vue3在样式中修改箭头图标无效,可能我设置不对,欢迎各位来交流指导 转变思路:隐藏箭头&…...
HTML 音频(Audio)
HTML 音频(Audio) HTML5 引入了新的音频标签 <audio>,使得在网页上嵌入音频文件变得更加简单。在此之前,播放音频通常需要依赖于第三方插件,如 Flash。但随着 HTML5 的普及,浏览器原生支持音频播放,极大地提升了用户体验和网页性能。 基本用法 要使用 HTML5 的音…...
linux音视频采集技术: v4l2
简介 在 Linux 系统中,视频设备的支持和管理离不开 V4L2(Video for Linux 2)。作为 Linux 内核的一部分,V4L2 提供了一套统一的接口,允许开发者与视频设备(如摄像头、视频采集卡等)进行交互。无…...
基于高斯混合模型的数据分析及其延伸应用(具体代码分析)
一、代码分析 (一)清除工作区和命令行窗口 clear; clc;clear;:该命令用于清除 MATLAB 工作区中的所有变量,确保代码运行环境的清洁,避免之前遗留的变量对当前代码运行产生干扰。例如,如果之前运行的代码中…...
内网基础-防火墙-隧道技术
内网对抗-网络通讯篇&防火墙组策略&入站和出站规则&单层双层&C2正反向上线 关闭第一个防火墙: 第一个上线就走反向或者正向 第二个上线走反向(第二个防火墙阻止入站) 关闭第二个防火墙: 第一个上线就走反向&a…...
123.【C语言】数据结构之快速排序挖坑法和前后指针法
目录 1.挖坑法 执行流程 代码 运行结果 可读性好的代码 2.前后指针法(双指针法) 执行流程 单趟排序代码 将单趟排序代码改造后 写法1 简洁的写法 3.思考题 1.挖坑法 执行流程 "挖坑法"顾名思义:要有坑位,一开始将关键值放入临时变量key中,在数组中形成…...
【沉默的羔羊心理学】汉尼拔的“移情”游戏:操纵与理解的艺术,精神分析学视角下的角色互动
终极解读《沉默的羔羊》:弗洛伊德精神分析学视角下的深层剖析 关键词 沉默的羔羊弗洛伊德精神分析学角色心理意识与潜意识性别与身份 弗洛伊德精神分析学简介 弗洛伊德的精神分析学是心理学的一个重要分支,主要关注人类行为背后的无意识动机和冲突。…...
Bytebase 3.0.1 - 可配置在 SQL 编辑器执行 DDL/DML
🚀 新功能 新增环境策略,允许在 SQL 编辑器内直接执行 DDL/DML 语句。 支持为 BigQuery 数据脱敏。 在项目下新增数据访问控制及脱敏管理页面。 在数据库页面,支持回滚到变更历史的某个版本。 🔔 兼容性变更 禁止工单创建…...
从零手写线性回归模型:PyTorch 实现深度学习入门教程
系列文章目录 01-PyTorch新手必看:张量是什么?5 分钟教你快速创建张量! 02-张量运算真简单!PyTorch 数值计算操作完全指南 03-Numpy 还是 PyTorch?张量与 Numpy 的神奇转换技巧 04-揭秘数据处理神器:PyTor…...
git使用指南-实践-搭建git私服
一.创建git私服的核心基础 所谓的git私服,其实就是在一个服务器上创建一个个的git仓库,并且这些仓库允许其在一个网络上被其他用户访问。 创建一个最素的git私服:随便找一台linux服务器,这里假设其ip为192.168.0.6,使…...
Node.js JXcore 打包教程
Node.js JXcore 打包教程 介绍 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它允许开发者使用 JavaScript 编写服务器端和网络应用程序。JXcore 是一个流行的 Node.js 发行版,它支持将 Node.js 应用程序打包成单一的可执行文件,使得部署和分发变得更加容易…...
Xshell 8 最新中文免安装绿色版
前言 Xshell8是一个非常受欢迎的远程连接管理软件,它的界面简单易懂,用起来特别方便。能支持好多种连接方式,比如SSH1、SSH2、SFTP、TELNET等等,还有串行协议和其他一些高级功能,基本上你想连什么都能满足。而且&…...
结构型模式4.装饰器模式
结构型模式 适配器模式(Adapter Pattern)桥接模式(Bridge Pattern)组合模式(Composite Pattern)装饰器模式(Decorator Pattern)外观模式(Facade Pattern)享元…...
备考蓝桥杯:顺序表详解(静态顺序表,vector用法)
目录 1.顺序表的概念 2.静态顺序表的实现 总代码 3.stl库动态顺序表vector 测试代码 1.顺序表的概念 要理解顺序表,我们要先了解一下什么是线性表 线性表是n个具有相同特征的数据元素的序列 这就是一个线性表 a1是表头 a4是表尾 a2是a3的前驱 a3是a2的后继 空…...
使用uniapp 微信小程序一些好用的插件分享
总结一下自己在开发中遇见的一问题,通过引入组件可以快速的解决 1.zxz-uni-data-select 下拉框选择器(添加下拉框检索,多选功能,多选搜索功能,自定义 下拉框插件,使用这个的原因是因为 uniui uview 组件库下拉框太…...
当遇到 502 错误(Bad Gateway)怎么办
很多安装雷池社区版的时候,配置完成,访问的时候可能会遇到当前问题,如何解决呢? 客户端,浏览器排查 1.刷新页面和清除缓存 首先尝试刷新页面,因为有时候 502 错误可能是由于网络临时波动导致服务器无法连…...
R语言安装教程与常见问题
生物信息基础入门笔记 R语言安装教程与常见问题 今天和大家聊一个非常基础但是很重要的技术问题——如何在不同操作系统上安装R语言?作为生物信息学数据分析的神兵利器,R语言的安装可谓是入门第一步,学术打工人的必备技能。今天分享在Windows…...
windows 下基于docker 部署 guacamole
背景 Apache Guacamole 是一种无客户端或插件的远程桌面网关。它支持多个标准协议,如 VNC、RDP 和 SSH等。记录下部署过程。 步骤 1, 安装docker desktop choco install docker-desktop -y 注: 若windows 11还未安装wsl,则需要…...
JVM实战—OOM的生产案例
1.每秒仅上百请求的系统为何会OOM(RPC超时时间设置过长导致QPS翻几倍) (1)案例背景 在这个案例中,一个每秒仅仅只有100请求的系统却因频繁OOM而崩溃。这个OOM问题会涉及:Tomcat底层工作原理、Tomcat内核参数的设置、服务请求超时时间。 (2)系统发生OOM的…...
oracle闪回恢复数据:(闪回查询,闪回表,闪回库,回收站恢复)
oracle的闪回查询,可以查询提交在表空间的闪回数据,并可以还原所查询的数据,用于恢复短时间内的delele 或者 update 误操作,非常方便,缺点是只能恢复大概几小时内的数据。 文章目录 概要闪回查询恢复数据的主要方法包括…...