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

iOS - 原子操作

在 Objective-C 运行时中,原子操作主要通过以下几种方式实现:

1. 基本原子操作

// 原子操作的基本实现
#if __has_feature(c_atomic)#define OSAtomicIncrement32(p)        __c11_atomic_add((_Atomic(int32_t) *)(p), 1, __ATOMIC_RELAXED)
#define OSAtomicDecrement32(p)        __c11_atomic_sub((_Atomic(int32_t) *)(p), 1, __ATOMIC_RELAXED)
#define OSAtomicIncrement32Barrier(p) __c11_atomic_add((_Atomic(int32_t) *)(p), 1, __ATOMIC_SEQ_CST)
#define OSAtomicDecrement32Barrier(p) __c11_atomic_sub((_Atomic(int32_t) *)(p), 1, __ATOMIC_SEQ_CST)#else// 使用内联汇编实现原子操作
static ALWAYS_INLINE int32_t 
OSAtomicIncrement32(volatile int32_t *value) {return __sync_fetch_and_add(value, 1) + 1;
}static ALWAYS_INLINE int32_t 
OSAtomicDecrement32(volatile int32_t *value) {return __sync_fetch_and_sub(value, 1) - 1;
}#endif

2. 自旋锁实现

typedef struct {volatile int32_t value;
} OSSpinLock;// 自旋锁的原子操作
static ALWAYS_INLINE void
OSSpinLockLock(volatile OSSpinLock *lock)
{do {while (lock->value != 0) {// 忙等待__asm__ volatile ("pause");}} while (!OSAtomicCompareAndSwap32(0, 1, &lock->value));
}static ALWAYS_INLINE bool
OSSpinLockTry(volatile OSSpinLock *lock)
{return OSAtomicCompareAndSwap32(0, 1, &lock->value);
}static ALWAYS_INLINE void
OSSpinLockUnlock(volatile OSSpinLock *lock)
{OSAtomicAnd32Barrier(0, &lock->value);
}

3. 比较和交换操作

// 原子比较和交换操作
static ALWAYS_INLINE bool
OSAtomicCompareAndSwapPtr(void *oldp, void *newp, void *volatile *dst)
{return __sync_bool_compare_and_swap(dst, oldp, newp);
}static ALWAYS_INLINE bool
OSAtomicCompareAndSwapLong(long oldl, long newl, volatile long *dst)
{return __sync_bool_compare_and_swap(dst, oldl, newl);
}static ALWAYS_INLINE bool
OSAtomicCompareAndSwap32(int32_t old, int32_t new, volatile int32_t *dst)
{return __sync_bool_compare_and_swap(dst, old, new);
}

4. 内存屏障

// 内存屏障实现
#define OSMemoryBarrier()  __sync_synchronize()static ALWAYS_INLINE void
OSMemoryBarrierBeforeUnlock()
{
#if defined(__arm__) || defined(__arm64__)OSMemoryBarrier();
#endif
}

5. 原子引用计数操作

inline bool 
objc_object::rootTryRetain()
{return sidetable_tryRetain() || rootRetain_overflow(true);
}inline bool 
objc_object::sidetable_tryRetain()
{SideTable& table = SideTables()[this];bool result = false;table.lock();RefcountMap::iterator it = table.refcnts.find(this);if (it != table.refcnts.end()) {RefcountMap::value_type &pair = *it;if (pair.second & SIDE_TABLE_RC_PINNED) {pair.second += SIDE_TABLE_RC_ONE;result = true;}else if (pair.second & SIDE_TABLE_RC_WEAKLY_REFERENCED) {pair.second = SIDE_TABLE_RC_ONE | SIDE_TABLE_RC_WEAKLY_REFERENCED;result = true;}}table.unlock();return result;
}

6. 原子属性访问器

// 原子属性的 getter
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;
}// 原子属性的 setter
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy) 
{if (!atomic) {*((id *)((char *)self + offset)) = newValue;return;}spinlock_t& slotlock = PropertyLocks[GOODHASH(offset)];slotlock.lock();*((id *)((char *)self + offset)) = newValue;slotlock.unlock();
}

7. 原子操作的使用场景

1. 引用计数管理

// 原子递增引用计数
id objc_retain(id obj) {if (!obj) return obj;if (obj->isTaggedPointer()) return obj;return obj->retain();
}

2. 属性访问

// 原子属性的实现
@property (atomic) NSString *name;

3. 数据结构操作

// 线程安全的数组操作
- (void)addObject:(id)object {@synchronized(self) {[_array addObject:object];}
}

这些原子操作的实现保证了:

  • 原子性:操作要么完全执行,要么完全不执行
  • 可见性:一个线程的修改对其他线程立即可见
  • 有序性:防止指令重排导致的问题

通过这些机制,Objective-C 运行时能够保证多线程环境下的数据一致性和线程安全。

相关文章:

iOS - 原子操作

在 Objective-C 运行时中,原子操作主要通过以下几种方式实现: 1. 基本原子操作 // 原子操作的基本实现 #if __has_feature(c_atomic)#define OSAtomicIncrement32(p) __c11_atomic_add((_Atomic(int32_t) *)(p), 1, __ATOMIC_RELAXED) #define …...

Go语言的语法

Go语言入门与实战 引言 在当今的开发环境中,随着互联网的快速发展,程序员们面临着越来越复杂的系统需求。针对这些需求,Go语言(又称Golang)作为一种新的编程语言应运而生。Go语言由Google开发,它具有简单…...

【MySQL 保姆级教学】用户管理和数据库权限(16)

数据库账户管理是指对数据库用户进行创建、修改和删除等操作,以控制用户对数据库的访问权限。通过账户管理,可以设置用户名、密码、主机地址等信息,确保数据库的安全性和可控性。例如,使用 CREATE USER 创建用户,ALTER…...

什么是 ES6 “模板语法” ?

ES6 提出了“模板语法”的概念。在 ES6 以前,拼接字符串是很麻烦的事情 var name css var career coder! var hobby [coding ,"writing] var finalString my name is name ,I work as a career I love hobby[0] and hobby[1]仅仅几…...

[项目实战2]贪吃蛇游戏

目录 贪吃蛇游戏:: 一、游戏效果及功能实现: 1.规则 ​​​​​​​ ​​​​​​​ ​​​​​​​ 2.基本功能实现 ​​​​​​​ ​​​​​​​ ​​​​​​​ 3.技术要点 ​​​​​​​…...

关于FPGA中添加FIR IP核(采用了GOWIN EDA)

文章目录 前言一、IP核二、MATLAB文件三、导出系数COE文件1.设计滤波器2.用官方的matlab代码或者直接用文本文件 四、进行模块化设计源文件 前言 FIR滤波器的特点是其输出信号是输入信号的加权和,权值由滤波器的系数决定。每个系数代表了滤波器在特定延迟位置上的“…...

1. 使用springboot做一个音乐播放器软件项目【前期规划】

背景: 现在大部分音乐软件都是要冲会员才可以无限常听的。对于喜欢听音乐的小伙伴,资金又比较紧张,是那么的不友好。作为程序员的我,也是喜欢听着歌,敲着代码。 最近就想做一个音乐播放器的软件,在内网中使…...

【Dify】Dify自定义模型设置 | 对接DMXAPI使用打折 Openai GPT 或 Claude3.5系列模型方法详解

一、Dify & DMXAPI 1、Dify DIFY(Do It For You)是一种自动化工具或服务,旨在帮助用户简化操作,减少繁琐的手动操作,提升工作效率。通过DIFY,用户能够快速完成任务、获取所需数据,并且可以…...

【Rust自学】10.8. 生命周期 Pt.4:方法定义中的生命周期标注与静态生命周期

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 10.8.1. 方法定义中的生命周期标注 还记得在上一篇文章 10.7. 生命周期 Pt.3 中所提到的省略生命周期的三条规则吗: 规则1&…...

121 买入股票的最佳时机

思路1: 买的那天一定是卖的那天之前的最小值。 每到一天,维护那天之前的最小值即可。 假设第一天是最小值,最大值初始化为0,当以后某天的价格小于最小值时,将最小值更新 当天价格大于最小值,说明有利可图…...

PID学习资料

TI公司的CONTROLSUITE https://www.ti.com.cn/tool/cn/CONTROLSUITE学点PID专栏-小麦大叔PID控制器算法系列TI公开培训(中文字幕) 电机控制,PI控制器,PID控制器和现场定向控制 书籍: Advanced PID Control先进PID控制及其MATLAB仿真Practic…...

采用标准化的方式开展设计-研发中运用设计模式

概述 实现规范化、标准化的引导式设计,以业务需求为输入,识别业务特点,并通过引导式设计,找到最适合的设计模式、具体方案,汇总成为应用的设计,拉齐各应用的设计一的致性。 采用标准化的方式开展设计…...

【Linux系列】并发与顺序执行:在 Linux 脚本中的应用与选择

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Scala语言的数据库交互

Scala语言的数据库交互 引言 在当今互联网应用的开发中,数据库几乎是每一个应用程序中不可或缺的一部分。选择合适的编程语言和工具与数据库进行交互,对于提升开发效率和应用性能至关重要。Scala作为一种现代的多范式编程语言,结合了面向对…...

字节青训十五题-Java-数字字符串格式化

问题 问题描述 小M在工作时遇到了一个问题,他需要将用户输入的不带千分位逗号的数字字符串转换为带千分位逗号的格式,并且保留小数部分。小M还发现,有时候输入的数字字符串前面会有无用的 0,这些也需要精简掉。请你帮助小M编写程…...

搭建一个本地轻量级且好用的学习TypeScript语言的环境

需求说明 虽然 TypeScript 的在线 Playground 很方便 https://www.tslang.com.cn/play/,但毕竟是在浏览器中使用,没有本地的 IDE 那么顺手。所以我想搭建一个本地类似 Playground 的环境,这样在学习 TypeScript 的过程中,可以更方…...

apex安装

安装过程复杂曲折,网上说的很多办法,貌似成功了,实际还是没起作用。 先说成功过程,执行下面命令,安装成功(当然,前提是你要先配置好编译环境): (我的环境&a…...

会员制电商创新:开源 AI 智能名片与 2+1 链动模式的协同赋能

摘要:本文聚焦于电商领域会员制的关键作用,深入探讨在传统交易模式向数字化转型过程中,如何借助开源 AI 智能名片以及 21 链动模式商城小程序,实现对会员数据的精准挖掘与高效利用,进而提升企业的营销效能与客户洞察能…...

Vue 3 和 Electron 来构建一个桌面端应用

我们将使用 Vue 3 和 Electron 来构建一个桌面端应用,该应用可以通过 Websocket 与服务器进行通信,并实现心跳检测、客户端上线、获取资产信息以及修改资产状态的功能。以下是实现步骤的概述: 项目结构:创建一个 Vue 3 项目&…...

生物医学信号处理--绪论

前言 参考书籍:刘海龙,生物医学信号处理,化学工业出版社 生物医学信号分类 1、由生理过程自发或者诱发产生的电生理信号和非电生理信号 • 电生理信号:ECG/心电、EEG/脑电、EMG/肌电、 EGG/胃电、 EOG/眼电 • 非电生理信号&am…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...