objective-c - 原子对于合成原语真的意味着什么吗?

标签 objective-c multithreading

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

在 Objective-C 中也是如此吗?我读到将 atomic 放在变量上本质上会导致合成的 getter 和 setter 使用锁,类似于在 Java 中使用同步方法。而且我读到这样做的原因是一个对象在被另一个线程读取时不会被部分修改。

但是原始类型是否像在 Java 中一样不会被部分修改?如果是这样的话,我似乎可以使用与 Java 相同的旧范例在线程之间共享数据。但是 atomic 关键字对于原始类型来说毫无意义,对吗?

我还读到一个比使用原子变量更健壮和更快的解决方案是在使用它们之前复制对象,如果它们是从多个线程访问的。但我不确定如何实现。非原子对象在复制过程中不能被修改,从而破坏副本吗?

最佳答案

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

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

Apple 通过 OSAtomic.h 公开了一些用于原子操作的 C 函数直接映射到 CPU 为实现并发机制提供的专用原子指令。与通过笨拙的互斥锁相比,您可以更直接地使用其中之一。

Objective-C 中的常见模式是:

  • 不可变对象(immutable对象)和功能转换——也有内存管理原因,但这部分是为什么 NSString , NSArray等与 NSMutableString 特别不同, NSMutableArray等;
  • 串行调度队列,可以与复制-修改-替换相结合,通过在队列上复制,从其他地方去修改,然后跳回队列进行替换;
  • 这样@synchronized小号,NSConditionLock s 或其他适当的显式同步机制。

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

关于objective-c - 原子对于合成原语真的意味着什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18668082/

相关文章:

C#/.NET : Testing BackgroundWorker with NUnit

c# - 在 C# 中持续运行进程的最佳实践

java - Java中的线程安全交换

java - 如何从 JAVA 字符串(文件路径)发送到 C?

Java 线程似乎运行多次

objective-c - 为什么NSString比较: return NSOrderedSame when the strings are different?

objective-c - 使用常量 NSString 作为 NSUserDefaults 的键

objective-c - Alpha 使用 UIView animateWithDuration : instead of animating 立即改变

objective-c - NSArray 的字符串排序问题

ios - CALayer : Where does the implicit animation comes from?