原子实际上对合成原语意味着什么吗?

Ten*_*r04 6 multithreading objective-c

在Android中,我可以安全地从不同的线程访问和修改基本类型.我用它在我的OpenGL绘制循环和在主线程Android UI中修改的用户设置之间共享数据.通过将每个设置存储在基本类型中并使每个设置独立于其他值,在不使用锁或synchronize关键字的情况下修改所有这些变量是线程安全的.

在Objective-C中也是如此吗?我读到将atomic放在变量上实质上会导致合成的getter和setter使用锁,类似于在Java中使用synchronized方法.我已经读过这个原因是因为一个对象在被另一个线程读取时不会被部分修改.

但原始类型是否可以安全地被部分修改,因为它们在Java中?如果是这种情况,似乎我可以使用Java中的相同旧范例在线程之间共享数据.但是原子关键字对于一个原始关键字是没有意义的,对吗?

我还读到,比使用原子变量更强大,更快的解决方案是在使用它们之前复制对象(如果从多个线程访问它们).但我不确定如何才能实现.非原子对象在复制过程中是否无法被修改,从而破坏了副本?

Tom*_*mmy 6

原始类型不能保证不被部分修改是安全的,因为原始类型的修改不能保证在C中是原子的,而Objective-C从那里继承.C只保证关注序列点,并且不要求两个序列点之间的处理是原子的 - 经验法则是每个完整表达式是一个序列点.

在实践中,修改原语通常是一个两步过程; 修改在寄存器中进行,然后写入存储器.写入本身不太可能不是原子的,但也不能保证它何时会发生与修改的对比.即使有volatile资格,提供的唯一保证就是序列点.

Apple通过OSAtomic.h公开了一些用于原子操作的C函数,这些函数直接映射到CPU为实现并发机制提供的专用原子指令.有可能你可以直接使用其中一个,而不是通过重型互斥锁.

Objective-C中的常见模式是:

  • 不可变对象和功能的转变-有内存管理方面的原因,以及但这是部分原因NSString,NSArray等等,都是专门从不同的NSMutableString,NSMutableArray等等;
  • 串行调度队列,可以通过复制队列,在其他地方进行修改,然后跳回队列进行替换,与复制 - 修改 - 替换相结合;
  • 这样的@synchronizeds,NSConditionLocks或其他适当的显式同步机制.

主线程本身是一个串行调度队列,这就是为什么你可以完全忽略并发问题,如果你限制自己.