关于atomic 是否是线程安全的问题
在 Objective - C 里,atomic 特性并不能保证对象是完全线程安全的,下面从其基本原理、部分线程安全场景以及局限性来详细说明:
先看一个例子
#import <Foundation/Foundation.h>@interface MyClass : NSObject
@property (atomic, assign) NSInteger count;
@end@implementation MyClass- (void)incrementCount {self.count = self.count + 1;
}@endint main(int argc, const char * argv[]) {@autoreleasepool {MyClass *myObject = [[MyClass alloc] init];dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);// 创建多个线程同时调用 incrementCount 方法for (int i = 0; i < 1000; i++) {dispatch_async(concurrentQueue, ^{[myObject incrementCount];});}// 等待所有任务完成dispatch_barrier_sync(concurrentQueue, ^{NSLog(@"Final count: %ld", (long)myObject.count);});}return 0;
}
多次执行结果
Final count: 996
Final count: 995
Final count: 991
Final count: 1000
Final count: 987
也就是说,结果是不确定,大概率不符合预期(≠1000),那么很显然多线程多操下,atomic并没有保证线程安全
咱们做如下修改,其他代码不变
@property (nonatomic, assign) NSInteger count;
多次执行结果
Final count: 561
Final count: 765
Final count: 567
Final count: 669
Final count: 720
比原来少了,也就是说atomic确实带来了一定的安全效果,只不过不完全保证
atomic 基本原理
atomic 是属性声明时的一个特性,使用 atomic 修饰的属性,在其生成的 setter 和 getter 方法里会加锁,以此来保证同一时间只有一个线程能对该属性进行读写操作。例如下面的代码:
@interface MyClass : NSObject
@property (atomic, strong) NSString *myString;
@end@implementation MyClass
// 编译器自动生成的类似 setter 方法,伪代码示意
- (void)setMyString:(NSString *)myString {@synchronized(self) {_myString = myString;}
}// 编译器自动生成的类似 getter 方法,伪代码示意
- (NSString *)myString {@synchronized(self) {return _myString;}
}
@end
部分线程安全场景
在单纯的属性读写操作中,atomic 能够在一定程度上保证线程安全。比如多个线程同时对 myString 属性进行读写操作,由于 setter 和 getter 方法加了锁,同一时间只会有一个线程执行读写操作,避免了数据竞争的问题。
atomic 的局限性
复合操作不安全:atomic 只能保证单个属性的 setter 和 getter 方法是线程安全的,对于复合操作无法保证线程安全。例如下面的代码:
@interface MyClass : NSObject
@property (atomic, assign) NSInteger count;
@end@implementation MyClass- (void)incrementCount {// 这是一个复合操作,先读再写self.count = self.count + 1;
}@end
在 incrementCount 方法中,先读取 count 的值,然后加 1 再赋值回去。虽然 count 属性使用了 atomic 修饰,但其 setter 和 getter 方法分别是线程安全的,但整个 incrementCount 操作不是原子的。在多线程环境下,可能会出现多个线程同时读取到相同的 count 值,然后各自加 1 再赋值回去,导致最终的 count 值不符合预期。
对象的其他操作不安全:atomic 仅针对属性的 setter 和 getter 方法加锁,对于对象的其他操作(如调用对象的方法)并不能保证线程安全。例如:
@interface MyClass : NSObject
@property (atomic, strong) NSMutableArray *myArray;
@end@implementation MyClass- (void)addObjectToArray:(id)object {// 这里对 myArray 进行操作,不是 setter 和 getter 方法,atomic 无法保证安全[self.myArray addObject:object];
}@end
在 addObjectToArray 方法中,虽然 myArray 属性使用了 atomic 修饰,但对 myArray 调用 addObject: 方法时并没有加锁,多个线程同时调用该方法可能会导致数据不一致的问题。
综上所述,atomic 只是在属性的基本读写操作上提供了一定的线程安全保障,但不能保证对象在多线程环境下的完全线程安全。如果需要更全面的线程安全,还需要使用其他同步机制(如 @synchronized、NSLock 等)来保护复合操作和对象的其他操作。
atomic vs. 真正的线程安全
atomic | @synchronized | GCD 串行队列 | NSLock | |
|---|---|---|---|---|
| 保证 setter/getter 线程安全 | ✅ | ✅ | ✅ | ✅ |
| 保证多个线程同时操作的安全性 | ❌ | ✅ | ✅ | ✅ |
| 推荐用于 | 简单属性 | 多个操作依赖同一数据 | 并发任务处理 | 多线程数据访问 |
| 性能 | 较好 | 稍差 | 高效 | 中等 |
相关文章:
关于atomic 是否是线程安全的问题
在 Objective - C 里,atomic 特性并不能保证对象是完全线程安全的,下面从其基本原理、部分线程安全场景以及局限性来详细说明: 先看一个例子 #import <Foundation/Foundation.h>interface MyClass : NSObject property (atomic, assi…...
在实体机和wsl2中安装docker、使用GPU
正常使用docker和gpu,直接命令行安装dcoker和,nvidia-container-toolkit。区别在于,后者在于安装驱动已经cuda加速时存在系统上的差异。 1、安装gpu驱动 在实体机中,安装cuda加速包,我们直接安装 driver 和 cuda 即可…...
HTTP3.0:QUIC协议详解
文章目录 HTTP3.0:QUIC协议详解QUIC是什么QUIC为什么这么快**连接建立快:一见钟情型协议****拥抱UDP:轻装上阵****多路复用:一条路走到黑****更智能的丢包处理****内置加密****网络切换无压力****拥塞控制更智能** QUIC的应用场景QUIC未来会取…...
【EXCEL】【VBA】处理GI Log获得Surf格式的CONTOUR DATA
【EXCEL】【VBA】处理GI Log获得Surf格式的CONTOUR DATA data source1: BH coordination tabledata source2:BH layer tableprocess 1:Collect BH List To Layer Tableprocess 2:match Reduced Level from "Layer"+"BH"data source1: BH coordination…...
【数据处理】使用python收集网络数据--爬虫基础
我们经常需要获取大量的网络数据用于分析,靠人工获取效率太低,所以用代码获取成为大多数人的主要选择,这里简单介绍下使用python进行网络数据爬取的方法 数据获取 由于我们没有各个平台的内部数据和接口,要想获取数据只能从网页…...
代码随想录二叉树篇(含源码)
二叉树与递归 前言226.翻转二叉树算法思路及代码solution 1 用分解问题的思路来解决solution 2 用遍历的思路来解决 101.对称二叉树算法思路及代码solution 104.二叉树的最大深度算法思路及代码solution 1 遍历solution 2 分解问题 111.二叉树的最小深度算法思路及代码solution…...
网络安全检测思路
对于主机的安全检测,我们通常直接采用nmap或者类似软件进行扫描,然后针对主机操作系统及其 开放端口判断主机的安全程度,这当然是一种方法,但这种方法往往失之粗糙,我仔细考虑了一下,觉 得按下面的流程进行…...
ios通过xib创建控件
之前写过ios动态创建控件及添加事件,纯手工代码写控件,虽然比较灵活,但是就是代码量比较多。这次我们通过xib来创建app下载列表项 AppView.xib。一个imageview,一个label,一个button构成 1.创建AppView.xib 2.再创建xib对应的mode࿰…...
跟着李沐老师学习深度学习(八)
数值稳定性 模型初始化和激活函数 数值稳定性 神经网络的梯度 考虑如下d层的神经网络(t代表层) 计算损失 l 关于参数 Wt 的梯度: 这样的矩阵乘法带来的问题: (1)梯度爆炸 (2)梯度…...
元宵小花灯
吃完饭散步回来的路上,看到一个小朋友拿着元宵小灯,后面的家长也闲适的哼着歌。 想起前阵子看到说,大人爱看小孩玩,也是共享那份天真快乐吧。 我小时候每年的元宵节,也有自己的小灯,那是九几年,…...
算法——搜索算法:原理、类型与实战应用
搜索算法:开启高效信息检索的钥匙 在信息爆炸的时代,搜索算法无疑是计算机科学领域中熠熠生辉的存在,它就像一把神奇的钥匙,为我们打开了高效信息检索的大门。无论是在日常生活中,还是在专业的工作场景里,…...
告别传统测量:三维扫描仪测量工件尺寸
在现代制造业中,精确测量工件尺寸是确保产品质量和生产效率的关键环节。然而,传统测量方法往往存在效率低下、精度不足以及操作复杂等问题,难以满足高精度和复杂形状工件的测量需求。 传统工件尺寸测量主要依赖于卡尺、千分尺、三坐标测量仪…...
win32汇编环境,对话框程序使用跟踪条(滑块)控件示例一
;运行效果 ;win32汇编环境,对话框程序使用跟踪条控件示例一 ;生成2条横的跟踪条,分别设置不同的数值范围,设置不同的进度副度的例子 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>>…...
WordPress 角标插件:20 种渐变色彩搭配,打造专属菜单标识
源码介绍 WordPress 角标插件使用教程 本插件旨在为 WordPress 菜单添加角标,并且支持 20 种不同的角标样式。 使用步骤 您可以在 WordPress 后台的“插件”页面中,找到“WordPress 角标插件”,然后点击激活按钮。您需要进入主题的菜单设置…...
【鸿蒙开发】第二十九章 Stage模型-应用上下文Context、进程、线程
目录 1 Stage模型基本概念 1.1 开发流程 3 应用上下文Context的典型使用场景 3.1 获取应用文件路径 3.2 获取和修改加密分区 3.3 获取本应用中其他Module的Context 3.4 订阅进程内UIAbility生命周期变化 4 进程 4.1 概述 5 线程 5.1 线程类型 5.2 使用EventHub进行线…...
window 安装GitLab服务器笔记
目录 视频: 资源: Linux CeneOS7: VMware: Linux无法安装 yum install vim -y 1.手动创建目录 2.下载repo PS 补充视频不可复制的代码 安装GitLab *修改root用户密码相关(我卡在第一步就直接放弃了这个操作&…...
3dgs 2025 学习笔记
CVPR 2024 3D方向总汇包含(3DGS、三维重建、深度补全、深度估计、全景定位、表面重建和特征匹配等)_cvpr2024-structure-awaresparse-viewx-ray3dreconstr-CSDN博客 https://github.com/apple/ml-hugs 3DGS COLMAP-Free 3D Gaussian Splatting ⭐code &…...
2024.1.2版本Android Studio gradle下载超时问题处理
一、问题背景 在项目的根build.gradle里面配置了以下地址后,依旧下载gradle包失败,平常如果出现第三方库或者gradle下载失败,配置以下地址,一般可以下载成功 maven { url https://maven.aliyun.com/repository/public } maven { url https://maven.aliyun.com/nex…...
ffmpeg学习:ubuntu下编译Android版ffmpeg-kit
文章目录 前言一. 配置环境1.1 虚拟机版本1.2 安装Android环境1.2.1 Android SDK安装1.2.2 Android NDK安装 1.3 编译前的准备工作1.3.1 libtasn1-1安装1.3.2 meson安装1.3.3 harfbuzz下载 二. 编译ffmpeg-kit三. 总结 前言 ffmpeg-kit是一款跨多个平台的,用于在应…...
mydb:TM实现
一、说明 TM就是事务管理:实现对于事务的新增(active)、事务的状态修改(commit、abort)、事务的状态判断 二、事务管理 2.1创建xid文件/打开xid文件 创建xid、写一个空的 XID 文件头并创建TM public static Transac…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
