关于在c#中设置简单属性的非线程安全是什么?

时间:2015-08-01 09:00:30

标签: c# multithreading thread-safety

我已经阅读了大量关于如何使属性线程安全的讨论和示例。 this threadsafe wrapper class

页面上有一个

给出的例子是:

internal class MyThreadSafeCass
{
    // *** Property ***
    private int m_Property = 0;

    // *** Thread-safe access to Property using locking ***
    internal int Property
    {
        get
        {
            return m_Property;
        }
        set
        {
            m_Property = value;
        }
    }
}

很清楚这里发生了什么,以及锁在做什么,但我很难理解为什么需要它。为什么以下线程安全?什么可能出错?

noscroll = pageScroll === 0;

2 个答案:

答案 0 :(得分:0)

表达式如下:m_Property ++;在多个线程并行返回不同的值。特别是在多核cpu上。

  • 旧值被加载到cpu的缓存中。
  • 该值将由cpu
  • 递增
  • 新值将保存回内存。

示例:

  • 核心一个将加载值为10
  • 核心2将与核心值
  • 同时加载值10
  • 都添加一个(值为11)
  • 两者都会将数据保存回内存
  • 结果将是11。
  • 但你希望12

有关详细信息,请参阅this

答案 1 :(得分:0)

@Enigmativity通过链接到this blog about skipping locks来获取这里的荣誉(如果不是点数,不幸的是),而this blog about CPU reordering optimizations又链接到{{3}},这是答案的真正含义。

总之,CPU可以(并且确实)对代码应用优化,这涉及更改执行读/写的顺序。这些更改保证在它们执行的线程内是一致的和不可察觉的。但是,它们不能(不能)保证跨多个线程访问共享内存的一致性。如初始问题中的示例所示,锁定会限制访问此共享内存以恢复一致性。

正如我所说,这是一个总结。我不能在上面链接的博客中添加任何内容,因此会推迟有兴趣知道完整答案的人跟随这些链接。

@Enigmativity,如果您这样发布,我仍会接受这个作为您的回答。否则,我会接受这个答案并关闭它。