这是线程安全的原子或原子不?这是线程安全的原子或原子不?(Which is threadsafe a

2019-05-12 23:03发布

我搜查,发现不可改变是线程安全的,而可变不是。 这可以。 但我得到了带有误导性质的原子与非原子有关线程安全注意事项,博客,答案,请给的答案的解释。

假设有一个名为“名”原子串属性,如果你调用[self setName:@"A"]从线程A,调用[self setName:@"B"]从线程B,并调用[self name]从螺纹C,然后在不同的线程中的所有操作将被连续执行,这意味着,如果一个线程正在执行调节器或吸气,然后其他线程将等待。 这使得“名称”属性读/写安全的,但如果另一个线程调用d [name release]同时则是因为没有这里涉及的setter /吸气调用此操作可能会产生崩溃。 这意味着将对象读/写安全(原子),但不是线程安全作为另一个线程可以同时发送任何类型的消息到该对象。

如果属性“名称”是非原子,然后在上面的例子中的所有线程 - A,B,C和d将执行同时产生任何不可预知的结果。 在的原子的情况下,无论是A,B或C中的一个将执行第一但仍d可以并行执行。

在这是你的意见将帮助我们....

我的问题是,“这是线程安全的可可,原子或非原子?”

Answer 1:

对于ObjC属性- 无论是线程安全的

原子是线程错误的能力更强。 总的来说,这是一个奇怪的默认值。 你将有利于原子的情况是非常少的。 原子可以提高准确性的概率,但它是在过低的水平被认为是一个适当的锁定装置的替代品。 因此,如果您需要线程安全的,你还需要上的原子读取上面的一些其他的同步原语/写。 如果你不需要线程安全(如实例是不可变的或打算只从主线程中运行),原子会增加什么。

作为线程错误不是“质量” -它用来掩盖真实的线程错误,使他们更难以复制和检测。

还要注意的是可变与不变类型实际上并不保证threadsafety。 “易变”可以在ObjC的名字被用来仅指接口 - 一个不变的情况下的内部实际上可能有内部可变状态。 总之,你不能假设具有可变的子类一类是线程安全的。


问题展开:

假设有一个名为“名”原子串属性,如果你调用[自我的setName:@“A”]从线程A,调用[自我的setName:@“B”]从线程B,并调用[自我名称]从螺纹C,然后在不同的线程中的所有操作将被连续执行,这意味着,如果一个线程正在执行调节器或吸气,然后其他线程将等待。

如果所有的线程试图读取和/或在同一时间写的财产,只有一个线程会在某一时刻访问,如果财产是原子其他的将被阻止。 如果属性是非原子,那么他们将都无人防守的读写访问在相同的“时间”变量。

如果另一个线程调用d [名称发行]同时则是因为没有这里涉及的setter /吸气调用此操作可能会产生崩溃。

正确。

这意味着将对象读/写安全(原子),但不是线程安全作为另一个线程可以同时发送任何类型的消息到该对象。

嗯,有真的有很多更给它。 常见的例子是:

    @interface MONPerson : NSObject

    @property (copy) NSString * firstName;
    @property (copy) NSString * lastName;

    - (NSString *)fullName;

    @end

原子,或者非原子,你会如果一个线程是从实例中读取需要一个同步机制(如锁),另一个是写它。 你可能最终得到一个MONPerson的firstName和另一个人的lastName的 - 对象可能已经改变之前,吸气的返回值,甚至还给你,或者会发生这种情况:

线程A:

p.firstName = @"Rob";

线程B:

p.firstName = @"Robert";

线程A:

label.string = p.firstName; // << uh, oh -- will be Robert

如果属性“名称”是非原子,然后在上面的例子中的所有线程 - A,B,C和d将执行同时产生任何不可预知的结果。

右 - 最初的症状可以是引用计数不平衡(泄漏,过放)。

在的原子的情况下,无论是A,B或C中的一个将执行第一但仍d可以并行执行。 在此请评论....

正确。 但是,如果你看一下上面的例子 - 单独的原子很少用于锁定一个合适的替代。 它必须看起来像这个:

线程A:

[p lock]; // << wait for it… … … …
// Thread B now cannot access p
p.firstName = @"Rob";
NSString fullName = p.fullName;
[p unlock];
// Thread B can now access p
label.string = fullName;

线程B:

[p lock]; // << wait for it… … … …
// Thread A now cannot access p
…
[p unlock];

原子存取可以平均比非原子访问慢了二十次。 同样,如果你的类必须是线程安全的,具有可变的状态,你可能会结束,当它在并发情况下运行时使用的锁。 适当的锁提供的所有保证你所需要的 - 原子访问器是多余的在这情况下,使用原子能只会增加CPU时间。 关于普通锁的另一个好处是,你有你需要的所有粒度 - 虽然它往往比用于原子能自旋锁重,所以它最终被速度非常快,如果你正确使用普通的锁,你通常需要较少的获取。



Answer 2:

原子保障了可变原子访问,但它不会使你的代码线程安全的。 无论是做非原子。

与“原子”,将合成的setter / getter方法将确保整个值总是从吸气退回或设置由设定器,设定器不论活性的任何其他线程。 所以,如果线程A是在吸气的中间,而线程B调用的二传手,实际可行的值将返回给调用者在答:对于非原子,你有没有这样的保证。



Answer 3:

原子使得执行以下操作线程安全的。

self.myProperty = value;

要么

id value = self.myProperty

它不会使下面的线程安全

[myPorperty addObject:value];

原子使得线程安全设置或获取的属性,但它不会使调用该属性本身是线程安全的任何方法。

设置或获取值可以采取多个CPU的指令,因此这意味着设置或获取虽然可以被打断了一半,而另一个线程可以做的一件事情,在设置或获取值无效前一个线程的进度。

原子说设置或在某种程度上获得的价值,使得它发生,如果它发生在一个不可分割的指令,因此没有其他的线程可以在半路上步和搞砸。

不可变对象是线程安全的简单,因为你不能改变他们的,因为你可以从一个不可变对象的属性更改另一个使部分不会被THEAD安全的,除非你把它的原子。



Answer 4:

有产品,其所需的线程安全ARC之前(也可能仍然是)未提到“原子”其他属性。 首先解释为什么它的需要:假设没有ARC,你读一个对象的属性,并立即保留。 但另一个线程可以进来只是你们之间的读取性能和保留通话,对象属性设置为无,导致被释放的对象。 您发送保留解除分配的对象,这是不健康的。 这将是一种非常罕见的错误,因为它只有在时机正好发生。 为了防止这种情况,原子对象的属性总是返回自动释放的对象。



Answer 5:

1)两者都是非线程安全的。 2)原子是只有一个读写安全。 3)但是,如果你想使线程安全的,你需要实现某种锁定机制,以丝线犹如互斥锁,自旋锁。 更多... https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html



Answer 6:

你应该考虑实施一个锁定机构,因此不要将您的应用程序中获得的僵局。 此外,如果要实现核心数据,你应该在iOS线程安全读了。

看到。

http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html

http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html%23//apple_ref/doc/uid/10000057i-CH8-SW1



Answer 7:

非原子是线程安全的。 Guranted得到变量的值。



文章来源: Which is threadsafe atomic or non atomic?