VB.NET: 如果我总是在写操作后使用Thread.MemoryBarrier(),那么在每次读取之前是否需要调用Thread.MemoryBarrier()?

5

VB.Net没有C# volatile关键字的等效项,因此您必须手动实现volatile,通常是在读取和写入之前调用Thread.MemoryBarrier()来完成。因此,像这样的内容相当于声明C# volatile变量:

    ''' <summary>
    ''' Gets a value indicating whether this instance is disposed.
    ''' </summary>
    Public Property IsDisposed As Boolean
        Get
            Threading.Thread.MemoryBarrier()
            Return _isDisposed
        End Get
        Private Set(value As Boolean)
            _isDisposed = value
            Threading.Thread.MemoryBarrier()
        End Set
    End Property

如果我只通过setter写入变量,并且在那里写入后始终调用Thread.MemoryBarrier(),那么在读取之前是否需要内存屏障?

我可以安全地在读取之前删除Thread.MemoryBarrier()吗?

编辑:为了更清楚,我的问题是是否可以删除读取之前的Thread.MemoryBarrier()以便每次读取时都不需要内存屏障。


2
Volatile 应该在 VB.net 中工作,而 Thread 类包含像 VolatileRead 这样的方法。 - CodesInChaos
问题是,在读取之前,我能否安全地删除Thread.MemoryBarrier(),以避免在读取时产生不必要的内存屏障成本。 - Dalibor Čarapić
我非常确定,如果你将其删除,就可能会出现过期读取。 - CodesInChaos
2
无法移除它。顺便说一下,当你提出这个问题时,很可能你并没有正确地使用它。请先阅读这个链接:http://stackoverflow.com/a/27469253/17034。 - Hans Passant
互联网上的信息有些矛盾。请参考:http://www.albahari.com/threading/part4.aspx(摘录:Thread类中的静态VolatileRead和VolatileWrite方法在读/写变量时强制执行(技术上是超集)volatile关键字所做的保证。然而,它们的实现相对低效,因为它们实际上生成了完整的屏障)。 - Dalibor Čarapić
1个回答

2

您无法删除读取端的屏障,这一点很容易通过示例来展示。让我们使用这个读取器:

while (!IsDisposed); //reads _isDisposed
_isDisposed的值可以在此处明确缓存到寄存器中,以便新写入永远不会变得可见。这个循环可能是无限的(例如 - 其他影响也可能导致长时间延迟)。
更正式地说,_isDisposed的读取可以全部向上移动,以先于存储发生的时间运行。volatile存储会产生释放栅栏,意味着后面没有什么可以移动过去。但是,它们可以向前移动到之前的时间点。
使用Volatile类。或者,使用用C#编写的结构体作为该字段的包装器:
struct VolatileInt32Box { public volatile int Value; }

我将使用Hans Passant提出的VolatileRead/VolatileWrite解决方案。 - Dalibor Čarapić
@dcarapic 由于某些原因,这两种方法要慢得多。它们编译为方法调用。它们只有劣势。 - usr
不要按照Hans Pasant的建议(他提供的链接是http://stackoverflow.com/questions/27468923/best-way-to-implement-thread-safe-atomic-accessors-of-a-long-property-on-a-guara/27469253#27469253)。现在我还没有测试过,但是我从其他来源阅读到,C#的volatile关键字和VolatileWrite / VolatileRead应该具有类似的功能和速度。 - Dalibor Čarapić
我几天前在当前的4.5 JIT和下一代RyuJIT上进行了测试。RyuJIT生成的代码很好,而当前的JIT仍然令人失望。不考虑性能,我建议:使用更新的功能(Volatile类)。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接