我对atomic和nonatomic的理解

最近在写线程安全方面的总结,顺便也对原子操作复习了一波。有错误之处请各位朋友指点指点,在此谢谢。

介绍一下原子操作:

1、定义:

所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch。
如果这个操作所处的层(layer)的更高层不能发现其内部实现与结构,那么这个操作是一个原子(atomic)操作。
原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分。
将整个操作视作一个整体是原子性的核心特征。

2、实现:

原子性不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。
在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

property中的atomic和nonatomic的选择:

官方文档对于atomic的描述:

This means that the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads.
Because the internal implementation and synchronization of atomic accessor methods is private, it’s not possible to combine a synthesized accessor with an accessor method that you implement yourself. You’ll get a compiler warning if you try, for example, to provide a custom setter for an atomic, readwrite property but leave the compiler to synthesize the getter.

尝试为标志为atomic的属性重载setter方法得到警告如下:

Writable atomic property 'name' cannot pair a synthesized getter with a user defined setter

根据官方文档的提示,我猜测如果标志为atomic的属性被重载setter or getter时,因其内置的原子操作的实现是私有的,而我们重载出的setter和getter在调用时被优先寻址得到,且因并无实现原子操作(就算有也与系统内置有所差异)所以要求重新synthesize该属性,如果没有自实现原子操作,那么该setter或者getter接口就没有了该性质,那么该属性中atomic的mark也就毫无意义,这是被重载的情况。

如果属性未被重载,如文档所说在设置器和访问器的使用上是保持原子操作的,也就是能通过getter和setter完整地设置一个值(也就是原子操作)。这里的完整地设置一个值我的理解是不受其他指令的影响。但是实际的开发中,我们更加注重的是数据在使用中线程安全的问题,而非这个单纯的数据读写时的保持完整性。在线程安全得到保证时,因为资源的使用受到约束,属性上标志为atomic还是nonatomic已然无关紧要。而效率上而言,nonatomic缺少了对于总线的约束因此其速率比atomic较高。

同时也看了MrPeak的结论:
读写(load or store)的内存长度小于等于地址总线的长度,那么读写的操作是原子的,一次完成。比如bool,int,long在64位系统下的单次读写都是原子操作。

个人感觉其实也算不上是原子操作。看下原子操作的实现本质是CPU在若干条机器指令执行期对总线进行加锁,防止别的CPU通过总线对内存进行访问。在对变量的赋值操作过程,汇编下来会有读值到寄存器,寄存器赋值于内存中等若干指令,如果这些指令步骤是非连贯或者是受到多线程干扰(这是完全有可能的),那么说是一个原子操作也就不成立了。

另外苹果的编程指南中也提到:

Note: Property atomicity is not synonymous with an object’s thread safety.
属性的原子性与对象的线程安全无关。

描述一下线程安全问题:

重载的设置器与普通接口一样,因为代码块存在多个逻辑,都会受到线程干扰。
可以加个最简单也是最耗时的锁synchronized(确保ID唯一)使作用域内数据加锁,便保证的数据逻辑上的正确。

另外其实在我预想中会有这么一种情况:

 -[Atest setAge:] : 0
 -[Atest setAge1:] :1
 -[Atest setAge2:] :2

会打印上面这么几个结果,因为从多线程角度而言这几个情况也是有可能发生的,但是在运行过程,我加大了运算规模依然未找到这个情况,目前猜测是我的规模未够大,或者是编译器做了某一个优化导致这种情况并未发生。

总结:

1、原子操作对线程安全并无任何安全保证。被atomic修饰的属性(不重载设置器和访问器)只保证了对数据读写的完整性,也就是原子性,但是与对象的线程安全无关。
2、线程安全有保障、对性能有要求的情况下可使用nonatomic替代atomic,当然也可以一直使用atomic。

参考:

1、百度百科
2、官方文档
3、iOS多线程到底不安全在哪里?
4、原子操作 vs 非原子操作
5、stackoverflow

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342