如何在VB.net中指定volatile的等效项? [英] How do I specify the equivalent of volatile in VB.net?
本文介绍了如何在VB.net中指定volatile的等效项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试编写用于消息传递的呼叫队列的无锁版本.这不是认真的事情,只是为了学习线程.
I'm attempting to write a lock-free version of a call queue I use for message passing. This is not for anything serious, just to learn about threading.
我相对确定我的代码是正确的,除非指令已重新排序或在寄存器中完成.我知道我可以使用内存屏障来停止重新排序,但是如何确保立即将值写入内存?
I'm relatively sure my code is correct, except if the instructions are re-ordered or done in registers. I know I can use memory barriers to stop re-ordering, but how can I ensure values are written to memory immediately?
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 end up with a non-empty idle queue'
If first.next Is Nothing Then Return False
Threading.Thread.MemoryBarrier()
'Try to acquire'
Return Threading.Interlocked.Exchange(_running, 1) = 0
End Function
Private Function TryReleaseConsumer() As Boolean
Do
Threading.Thread.MemoryBarrier()
'Dont release while there are still things to consume'
If first.next IsNot Nothing Then Return False
Threading.Thread.MemoryBarrier()
'Release'
_running = 0
Threading.Thread.MemoryBarrier()
'It is possible that a new item was queued between the first.next check and releasing'
'Therefore it is necessary to check if we can re-acquire in order to guarantee we dont leave a non-empty queue idle'
If Not TryAcquireConsumer() Then Return True
Loop
End Function
Public Sub QueueAction(ByVal action As Action)
'Enqueue'
'Essentially, this works because each node is returned by InterLocked.Exchange *exactly once*'
'Each node has its .next property set exactly once, and also each node is targeted by .next exactly once, so they end up forming a valid tail'
Dim n = New Node(action)
Threading.Interlocked.Exchange(last, n).next = n
'Start the consumer thread if it is not already running'
If TryAcquireConsumer() Then
Call New Threading.Thread(Sub() Consume()).Start()
End If
End Sub
Private Sub Consume()
'Run until queue is empty'
Do Until TryReleaseConsumer()
first = first.next
Call first.action()
Loop
End Sub
End Class
推荐答案
使用BCL中的Thread.VolatileRead()
和VolatileWrite()
方法.
Use Thread.VolatileRead()
and VolatileWrite()
methods from the BCL.
http://msdn.microsoft.com/zh-cn/library/system.threading.thread.volatileread.aspx
这篇关于如何在VB.net中指定volatile的等效项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文