关于C#:哪个是线程安全的原子或非原子?

Which is threadsafe atomic or non atomic?

我搜索并发现不可变是线程安全的,而可变不是。这很好。但是我得到了误导性的笔记、博客、关于线程安全的原子和非原子的答案,请对答案作出解释。

假设有一个名为"name"的原子字符串属性,如果从线程a调用[self setName:@"A"]、从线程b调用[self setName:@"B"]、从线程c调用[self name],那么在不同线程上的所有操作都将连续执行,这意味着如果一个线程正在执行setter或getter,那么其他线程将等待。这使得属性"name"读/写安全,但如果另一个线程d同时调用[name release],那么此操作可能会导致崩溃,因为这里不涉及setter/getter调用。这意味着对象是读/写安全的(原子的),但不是线程安全的,因为其他线程可以同时向对象发送任何类型的消息。

如果属性"name"是非原子的,那么上面示例中的所有线程(a、b、c和d)都将同时执行,从而产生任何不可预知的结果。在原子的情况下,a、b或c中的任何一个将首先执行,但d仍然可以并行执行。

您对此的评论将有助于我们……

我的问题是,"可可中的哪一种是安全的,原子的还是非原子的?"


对于objc属性——线程安全也是如此。

Atomic更能抵抗线程错误。总的来说,这是一个奇怪的违约。你喜欢原子的场景很少。原子可以增加正确性的概率,但它的级别太低,不能被认为是适当锁定机制的替代品。因此,如果您需要线程安全,您仍然需要原子读/写之上的其他同步原语。如果您不需要线程安全(例如,实例是不可变的,或者只打算从主线程运行),那么Atomic将不会添加任何内容。

抵抗线程错误不是一种"质量"——它可以掩盖真正的线程错误,使它们更难重现和检测。

还要注意,可变类型和不可变类型实际上不能保证线程安全。在objc名称中,mutable'只能用于引用接口——不可变实例的内部实际上可能具有内部可变状态。简而言之,不能假定具有可变子类的类型是线程安全的。

问题扩展:

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 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.

嗯,还有很多。常见的例子是:

1
2
3
4
5
6
7
8
    @interface MONPerson : NSObject

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

    - (NSString *)fullName;

    @end

原子的或非原子的,如果一个线程正在从该实例读取,而另一个线程正在向其写入,则需要一个同步机制(例如锁)。您可能会得到一个monperson的firstname和另一个firstname——对象可能在getter的返回值返回给您之前发生了更改,或者这可能发生:

线程A:

1
p.firstName = @"Rob";

线程B:

1
p.firstName = @"Robert";

线程A:

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

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. Kindly comment on this....

对的。但是如果你看上面的例子——单原子很少是锁的合适替代品。它必须看起来像这样:

线程A:

1
2
3
4
5
6
7
[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:

1
2
3
4
[p lock]; // << wait for it… … … …
// Thread A now cannot access p

[p unlock];

原子存取器的平均速度比非原子存取慢20倍以上。另外,如果您的类需要是threadsafe并且具有可变状态,那么当它在并发场景中运行时,您可能最终会使用锁。正确的锁定提供了您所需要的所有保证——在这种情况下,原子访问器是多余的,使用原子只会增加CPU时间。常规锁的另一个好处是,您拥有所需的所有粒度——尽管它通常比原子使用的自旋锁重,但您通常需要较少的获取,因此,如果正确使用常规锁,最终会非常快。


原子保证对变量的原子访问,但它不会使代码线程安全。非原子也不是。

对于"原子",合成的setter/getter方法将确保始终从getter返回一个完整的值或由setter设置,而不管其他线程上的setter活动如何。因此,如果线程A在getter的中间,而线程B调用setter,那么实际的可行值将返回到a中的调用者。对于非原子的,您没有这样的保证。


原子使执行以下线程安全。

1
self.myProperty = value;

1
id value = self.myProperty

它不会使下列线程安全

1
[myPorperty addObject:value];

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

设置或获取值可能需要一个以上的CPU指令,这意味着设置或获取可以中途中断,另一个线程可以做一些事情,使上一个线程的设置或获取值的进度无效。

Atomic说以某种方式设置或获取值,这样它就像发生在一个不可分割的指令中一样发生,所以没有其他线程可以跨出一半来把事情搞砸。

不可变对象是线程安全的简单方法,因为您不能更改它们,因为您可以从一个不可变对象更改一个属性,从而使该部分不安全,除非您使其成为原子对象。


还有一个"原子"属性没有提到,这是在ARC之前线程安全所必需的(可能仍然是)。首先解释为什么需要它:假设没有ARC,您读取一个对象属性并立即保留它。但另一个线程可能正好在您读取属性和retain调用之间出现,将object属性设置为nil,导致对象被释放。将retain发送到未释放的对象,该对象不正常。这将是一个非常罕见的错误,因为它只发生在正确的时机。为了防止这种情况发生,原子对象属性总是返回自动释放的对象。


1)两者都是非线程安全的。2)Atomic只具有读写安全性。3)但是,如果要使线程安全,需要实现一些锁机制,例如互斥锁、旋转锁。多读…https://developer.apple.com/library/ios/documentation/cocoa/conceptive/multiphreading/threadsafety/threadsafety.html


你应该考虑实现一个锁定机制,这样你就不会在你的应用程序中出现死锁。另外,如果您正在实现核心数据,那么您应该阅读IOS线程安全性。

看。

http://developer.apple.com/library/ios/documentation/cocoa/conceptive/multiphreading/threasafetysummary/threasafetysummary.html

http://developer.apple.com/library/ios/documentation/cocoa/conceptive/multiphreading/threadsafety/threadsafety.html%23//apple_-ref/doc/uid/10000057i-ch8-sw1


非原子是线程安全的。保证获得变量的值。