我找不到任何 VolatileRead/write(尝试...)的例子,但仍然:
我何时应该使用volatilevs VolatileRead?
AFAIK的全部目的volatile是创造半围栏所以:
问题#1
那我为什么需要volatileRead?似乎volatile已经做好了工作.
另外 - 在C#中,所有写入都是易失性的(与Java中不同),无论您是写入volatile还是非易失性字段 - 所以我问:为什么我需要 volatileWrite?
问题2
这是实施VolatileRead:
[MethodImpl(MethodImplOptions.NoInlining)]
public static int VolatileRead(ref int address)
{
int num = address;
MemoryBarrier();
return num;
}
Run Code Online (Sandbox Code Playgroud)
为什么这条线路int num = address;在那里?他们已经有了明确保持价值的地址参数.
我已经在VB.NET中做了一段时间的简单多线程,并刚刚进入我的第一个大型多线程项目.我总是使用Synclock声明完成所有事情,因为我认为没有更好的方法.
我刚刚了解了这个Interlocked类 - 它看起来好像这一切:
Private SomeInt as Integer
Private SomeInt_LockObject as New Object
Public Sub IntrementSomeInt
Synclock SomeInt_LockObject
SomeInt += 1
End Synclock
End Sub
Run Code Online (Sandbox Code Playgroud)
可以用单个语句替换:
Interlocked.Increment(SomeInt)
Run Code Online (Sandbox Code Playgroud)
这会在内部处理所有锁定并修改数字.这比为简单操作编写自己的锁要简单得多(更长时间运行或更复杂的操作显然仍然需要自己的锁定).
当我可以使用这些Interlocked方法完成同样的事情时,我是否有理由使用专用锁定对象来进行自己的锁定?
我正在尝试编写一个用于消息传递的无锁版本的调用队列.这不是任何严肃的事情,只是为了了解线程.
我相对确定我的代码是正确的,除非指令被重新排序或在寄存器中完成.我知道我可以使用内存屏障来停止重新排序,但是如何确保将值立即写入内存?
Public Class CallQueue
Private first As New Node(Nothing) 'owned by consumer'
Private last As Node = first 'owned by producers'
Private Class Node
Public ReadOnly action As Action
Public [next] As Node
Public Sub New(ByVal action As Action)
Me.action = action
End Sub
End Class
Private _running As Integer
Private Function TryAcquireConsumer() As Boolean
Threading.Thread.MemoryBarrier()
'Dont bother acquiring if there are no items to consume'
'This unsafe check is alright because enqueuers call this method, so we never …Run Code Online (Sandbox Code Playgroud)