C#线程安全的静态成员 [英] C# thread safe static member
问题描述
我有一个C#类的静态成员,即从多个线程读取和写入一个线程。
据我所知答:64位读,写是不是在所有系统上的原子操作,所以我必须手动保证线程安全。
我对如何做到这一点的一些想法。
-
与和原子包装类,比如std ::原子在C ++中做到这一点。有没有类似的东西在C#中实现的?
-
使用volatile修饰符静态字段。然而,这是不允许的。为什么呢?
-
我终于做了以下内容:
私有静态对象tick_time_lock; 私有静态UINT64 _currentTickTime; 公共静态UINT64 CurrentTickTime { 得到 { 返回_currentTickTime; } 组 { 锁(tick_time_lock) { _currentTickTime =价值; } } }
这是使这个领域的正确方法是线程安全的?
这是使这个领域的正确方法是线程安全的?
一个监视器锁是没有意义的,除非的所有的访问特定资源的同步。把周围的设置锁定
访问是相当无用的,除非你的 GET
访问也锁定。正如你所说,读取和 UINT64
值写入不是原子在所有平台上。如果该字段读取 GET
访问时,只有第一个字已经写在设置
的访问,会发生什么?你会得到一个撕裂的阅读。
使用volatile修饰符静态字段。然而,这是不允许的。为什么呢?
C#语言设计者认为这是有益的,以保证所有挥发性
字段的访问是原子的。作为一个折衷,你不能宣布任何64位字段为挥发性
。我不知道是肯定的为什么的这一决定做出。也许他们想避免增加隐藏的开销,一些挥发性读/写操作,而是要求开发商依靠像 Thread.Volatile [读/写](REF长)$框架级别设施C $ C>处理64位值。
与和原子包装类,比如std ::原子在C ++中做到这一点。有没有类似的东西在C#中实现的?
是的。有通过 System.Threading.Interlocked
类,包括读
,<$ C $暴露框架级的原子操作C>交易所, CompareExchange
。
I have a C# class with a static member, that is read from multiple threads and written in one thread.
As far as I know Uint64 read and write is not an atomic operation on all systems, so I have to manually guarantee thread safety.
I had a few ideas about how to do this.
Do it with and atomic wrapper class, like std::atomic in c++. Is there something similar implemented in C#?
Use the volatile modifier with static field. However this is not allowed. Why?
I finally did the following:
private static object tick_time_lock; private static UInt64 _currentTickTime; public static UInt64 CurrentTickTime { get { return _currentTickTime; } set { lock (tick_time_lock) { _currentTickTime = value; } } }
Is this the correct way of making this field thread-safe?
Is this the correct way of making this field thread-safe?
A monitor lock is meaningless unless all accesses of a given resource are synchronized. Putting a lock around the set
accessor is rather useless unless you also lock on the get
accessor. As you say, reads and writes of UInt64
values are not atomic on all platforms. What happens if the field is read in the get
accessor when only the first word has been written in the set
accessor? You'd get a torn read.
Use the volatile modifier with static field. However this is not allowed. Why?
The C# language designers felt it was beneficial to guarantee that all volatile
field accesses are atomic. As a trade-off, you cannot declare any 64-bit field as volatile
. I do not know for certain why this decision was made. Perhaps they wanted to avoid adding "hidden" overhead to some volatile read/write operations and instead require developers to depend on framework-level facilities like Thread.Volatile[Read/Write](ref long)
for handling 64-bit values.
Do it with and atomic wrapper class, like std::atomic in c++. Is there something similar implemented in C#?
Yes. There are framework-level atomic operations exposed through the System.Threading.Interlocked
class, including Read
, Exchange
, CompareExchange
.
这篇关于C#线程安全的静态成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!