【发布时间】:2017-05-27 23:33:34
【问题描述】:
问题
我正在从事一个关注对象属性的线程安全性的项目。我知道,当属性是 NSString 之类的对象时,我可能会遇到多个线程同时读取和写入的情况。在这种情况下,您可能会收到损坏的读取,并且应用程序将崩溃或导致数据损坏。
我的问题是针对原始值类型属性,例如 BOOLs 或 NSIntegers。我想知道我是否会遇到类似的情况,即在从多个线程读取和写入时读取损坏的值(并且应用程序将崩溃)?无论哪种情况,我都对为什么感兴趣。
澄清 - 2017 年 1 月 13 日
我最感兴趣的是,原始值类型属性是否因多个线程同时访问而导致崩溃的可能性与 NSMutableString、自定义创建的对象等对象不同。此外,如果存在差异相对于多线程访问堆栈与堆上的内存时。
澄清 - 2017 年 12 月 1 日
感谢@Rob 在这里为我指出答案:stackoverflow.com/a/34386935/1271826!这个答案有一个很好的例子,表明根据您所使用的架构类型(32 位与 64 位),使用原始属性时可能会得到未定义的结果。
虽然这是朝着回答我的问题迈出的一大步,但我仍然想知道两件事:
- 在访问堆栈和堆上的原始值属性时是否存在多线程差异(如我之前的说明中所述)?
- 如果您将程序限制为在一种架构上运行,您是否仍会在访问原始值属性时发现自己处于不设防状态?为什么?
我应该注意到,在回答这个问题时,这里有很多关于原子与非原子的对话。虽然这通常是一个重要的概念,但这个问题与通过使用原子属性修饰符或任何其他线程安全方法(例如使用 GCD)来防止未定义的多线程行为几乎没有关系。
【问题讨论】:
-
使用原子属性可以避免任何读取“损坏”值的机会。但这并不一定能避免读取“不正确”的值。
-
是的,我熟悉使用原子与非原子,但是读取原始值类型属性的“损坏”值是否可能?如果有,为什么?
-
是的,有可能。如果您在 32 位目标上运行 stackoverflow.com/a/34386935/1271826 处的代码,您将看到损坏的值。
标签: objective-c multithreading crash primitive