C#线程安全的静态成员 [英] C# thread safe static member

查看:264
本文介绍了C#线程安全的静态成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#类的静态成员,即从多个线程读取和写入一个线程。

据我所知答:64位读,写是不是在所有系统上的原子操作,所以我必须手动保证线程安全。

我对如何做到这一点的一些想法。

  1. 与和原子包装类,比如std ::原子在C ++中做到这一点。有没有类似的东西在C#中实现的?

  2. 使用volatile修饰符静态字段。然而,这是不允许的。为什么呢?

  3. 我终于做了以下内容:

     私有静态对象tick_time_lock;
    私有静态UINT64 _currentTickTime;
    公共静态UINT64 CurrentTickTime
    {
        得到
        {
            返回_currentTickTime;
        }
        组
        {
            锁(tick_time_lock)
            {
                _currentTickTime =价值;
            }
        }
    }
     

这是使这个领域的正确方法是线程安全的?

解决方案
  

这是使这个领域的正确方法是线程安全的?

一个监视器锁是没有意义的,除非的所有的访问特定资源的同步。把周围的设置锁定访问是相当无用的,除非你的 GET 访问也锁定。正如你所说,读取和 UINT64 值写入不是原子在所有平台上。如果该字段读取 GET 访问时,只有第一个字已经写在设置的访问,会发生什么?你会得到一个撕裂的阅读。

  

使用volatile修饰符静态字段。然而,这是不允许的。为什么呢?

C#语言设计者认为这是有益的,以保证所有挥发性字段的访问是原子的。作为一个折衷,你不能宣布任何64位字段为挥发性。我不知道是肯定的为什么的这一决定做出。也许他们想避免增加隐藏的开销,一些挥发性读/写操作,而是要求开发商依靠像 Thread.Volatile [读/写](REF长)处理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.

  1. Do it with and atomic wrapper class, like std::atomic in c++. Is there something similar implemented in C#?

  2. Use the volatile modifier with static field. However this is not allowed. Why?

  3. 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屋!

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