哪个是线程安全的原子或非原子? [英] Which is threadsafe atomic or non atomic?

查看:97
本文介绍了哪个是线程安全的原子或非原子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索并发现immutable是线程安全,而mutable不是。这可以。
但我有误导性的笔记,博客,关于原子与非原子关于线程安全的答案,请解释一下答案。

I searched and found immutable are thread safe while mutable is not. This is fine. But i got misleading notes, blogs, answers about atomic vs non-atomic about thread safety, kindly give an explanation for the answer.

假设有一个如果从线程A调用 [self setName:@A] ,则调用 [self setName:@ B] ,并从线程C调用 [self name] ,则不同线程上的所有操作将被串行执行,如果一个线程正在执行setter或getter,那么其他线程将等待。这使得属性名称读/写安全,但如果另一个线程D同时调用 [name release] ,那么此操作可能会产生崩溃,因为没有setter / getter调用这里。这意味着对象是读/写安全(ATOMIC),但不是线程安全的,因为另一个线程可以同时向对象发送任何类型的消息。

Suppose there is an atomic string property called "name", and if you call [self setName:@"A"] from thread A, call [self setName:@"B"] from thread B, and call [self name] from thread C, then all operation on different thread will be performed serially which means if one thread is executing setter or getter, then other threads will wait. This makes property "name" read/write safe but if another thread D calls [name release] simultaneously then this operation might produce a crash because there is no setter/getter call involved here. Which means an object is read/write safe (ATOMIC) but not thread safe as another threads can simultaneously send any type of messages to the object.

如果属性name是非原子的,那么上面例子中的所有线程 - A,B,C和D将同时执行,产生任何不可预测的结果。在原子的情况下,A,B或C中的任一个将首先执行,但D仍然可以并行执行。

If the property "name" was nonatomic, then all threads in above example - A, B, C and D will execute simultaneously producing any unpredictable result. In case of atomic, Either one of A, B or C will execute first but D can still execute in parallel.

您的评论将帮助我们....

Yours comment on this will help us....

我的问题是,

And my question is, "which is thread safe in cocoa, atomic or non-atomic?"

推荐答案

对于ObjC属性 -

For ObjC Properties -- Neither are thread safe.

Atomic更容易受到线程错误的影响。总的来说,这是一个好奇的默认。你喜欢原子的方案很少。原子可以提高正确性的概率,但是它太低的水平被认为是适当的锁定机制的替代。因此,如果你需要线程安全,你仍然需要一些其他同步原语在原子读/写。如果你不需要线程安全(例如,实例是不可变的或者意图从主线程运行),atomic将不会添加任何东西。

Atomic is more resistant to threading errors. Overall, it is a curious default. The scenarios you would favor atomic for are very few. Atomic can increase the probability of correctness, but it's at too low a level be considered a substitute for a proper locking mechanism. Therefore, if you need thread safety, you still need some other synchronization primitive on top of the atomic reads/writes. If you don't need thread safety (e.g. the instance is immutable or intended to be run from the main thread only), atomic will add nothing.

对于线程错误的抗性不是一个质量 - 它用于掩盖真正的线程错误,使它们更难以重现,检测。

Being resistant to threading errors is not a 'quality' -- it serves to mask real threading errors and make them more difficult to reproduce and detect.

还要注意,mutable vs. immutable类型实际上并不保证threadafety。 Mutable可以在ObjC名称中使用,仅指向接口 - 不可变实例的内部实际上可能实际上具有内部可变状态。总之,你不能假设一个具有可变子类的类型是线程安全的。

Also note that mutable vs. immutable types do not actually guarantee threadsafety. 'Mutable' may be used in ObjC names to refer only to the interface -- the internals of an immutable instance may actually have internal mutable state. In short, you cannot assume that a type which has a mutable subclass is thread safe.

问题扩展:

Question Expanded:


假设有一个名为name的原子字符串属性,自身名称:@A],从线程B调用[self setName:@B],并从线程C调用[self name],那么将串行执行不同线程上的所有操作,线程正在执行setter或getter,则其他线程将等待。

Suppose there is an atomic string property called "name", and if you call [self setName:@"A"] from thread A, call [self setName:@"B"] from thread B, and call [self name] from thread C, then all operation on different thread will be performed serially which means if one thread is executing setter or getter, then other threads will wait.

如果所有线程尝试读取和/或写入属性同时,只有一个线程将有一次访问,其他将被阻止,如果属性是原子的。如果属性是非原子的,那么它们都将在同一时间对变量进行无保护的读写访问。

If all threads tried to read and/or write to the property at the same time, only one thread would have access at a time and the others would be blocked if the property were atomic. If the property were nonatomic, then they would all have unguarded read and write access to the variable at the same "time".


线程D同时调用[名称释放],则此操作可能会产生崩溃,因为此处不涉及setter / getter调用。

if another thread D calls [name release] simultaneously then this operation might produce a crash because there is no setter/getter call involved here.


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

Which means an object is read/write safe (ATOMIC) but not thread safe as another threads can simultaneously send any type of messages to the object.

好吧,真的有很多东西。常见的例子是:

Well, there's really a lot more to it. The common example is:

    @interface MONPerson : NSObject

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

    - (NSString *)fullName;

    @end

原子或非原子的,你需要一个同步机制(例如锁定),如果一个线程正在从该实例读取,另一个正在写入它。你可能会得到一个MONPerson的firstName和另一个lastName - 对象可能已经改变之前getter的返回值甚至返回给你,或者这可能发生:

Atomic, or nonatomic, you will need a synchronization mechanism (e.g. lock) if one thread is reading from that instance and another is writing to it. You may end up with one MONPerson's firstName and another's lastName -- The object may have changed before the getter's return value is even returned to you, or this can happen:

A:

p.firstName = @"Rob";

主题B:

p.firstName = @"Robert";

主题A:

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



是非原子的,则上面例子中的所有线程 - A,B,C和D将同时执行,产生任何不可预测的结果。

If the property "name" was nonatomic, then all threads in above example - A,B, C and D will execute simultaneously producing any unpredictable result.



<初始症状可以是引用计数不平衡(泄漏,过量释放)。

Right - initial symptoms can be reference count imbalances (leak, over-release).


在原子的情况下,A,B或C将首先执行,但D仍然可以并行执行。请对此进行评论....

In case of atomic, Either one of A, B or C will execute first but D can still execute in parallel. Kindly comment on this....

正确。但是,如果你看看上面的例子 - 原子独自很少是一个合适的替代锁。它应该看起来像这样:

Correct. But if you look at the example above -- atomic alone is rarely a suitable replacement for a lock. It would have to look like this instead:

主题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];

原子访问器的平均速度比非原子访问的平均速度快20倍。此外,如果您的类需要线程安全并且具有可变状态,那么在并发场景中操作时,您可能最终使用锁定。适当的锁定提供了您需要的所有保证 - 原子访问器在这种情况下是冗余的,使用原子只会增加CPU时间。关于常规锁的另一个好处是,你有你需要的所有粒度 - 虽然它通常比用于原子的自旋锁更重,你通常需要较少的获取,所以如果你正确使用正规锁定,它最终会非常快。

Atomic accessors can average over twenty times slower than nonatomic accesses. As well, if your class needs to be threadsafe and has mutable state, you will likely end up using a lock when it operates in a concurrent scenario. Proper locking provides the all guarantees you need -- atomic accessors are redundant in that scenario, using atomics would only add CPU time. Another good thing about the regular lock is that you have all the granularity you need -- although it is often heavier than the spin lock used for atomics, you will typically need fewer acquires so it ends up being very fast if you use regular locks correctly.

这篇关于哪个是线程安全的原子或非原子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆