[英]Lockfree Read value after Interlocked.Exchange?
讓我們說我們有這樣一個類:
public class Foo
{
private Bar bar = new Bar();
public void DoStuffInThread1()
{
var old = Interlocked.Exchange(ref bar,new Bar());
//do things with old
//everything is fine here, I'm sure I have the previous bar value
}
public void OtherStuffFromThread2()
{
//how do I ensure that I have the latest bar ref here
//considering mem cahces etc
bar.Something();
}
}
並且假設我們有兩個線程,一個在DoStuffInThread1
上DoStuffInThread1
,另一個在OtherStuffFromThread2
上OtherStuffFromThread2
。
如何確保thread2始終看到最新的bar
? 揮發無濟於事。 而且我不想要舊學校的鎖。 必須有一種方法來讀取條形碼的正確值,並以某種方式互鎖?
你錯過了這一點......
除非你這樣做:
public void OtherStuffFromThread2()
{
while (true)
{
//how do I ensure that I have the latest bar ref here
//considering mem cahces etc
bar.Something();
}
}
這是非常不可能的事情,幾乎所有你可以在OtherStuffFromThread2()
上使用等待thread1准備就緒的方法都會導致一個隱含的內存障礙 ...參見例如內存屏障生成器一些導致內存障礙的結構......
所以:
public void OtherStuffFromThread2()
{
Thread.Sleep(Timespan.FromMinutes(1));
// Implicit MemoryBarrier here :-)
//how do I ensure that I have the latest bar ref here
//considering mem cahces etc
bar.Something();
}
如果你真的想讀取變量的值,你可以讀取一個volatile變量,然后讀取你的變量(或者讀取兩次相同的volatile變量)。 為什么? 因為volatile讀取會導致獲取語義,這意味着它無法通過后續內存操作重新排序,請參閱https://msdn.microsoft.com/en-us/library/aa645755(v=vs.71).aspx :
讀取volatile字段稱為volatile讀取。 易失性讀取具有“獲取語義”; 也就是說,保證在指令序列之后發生的任何內存引用之前發生。
所以,如果你這樣做:
private static int myuselessvolatilefieldthatcanbestatic;
private int thefieldiwanttoread;
接着
var useless = myuselessvolatilefieldthatcanbestatic;
var iwanttoknow = thefieldiwanttoread;
thefieldiwanttoread
將包含一個值,該值將在對myuselessvolatilefieldthatcanbestatic
的新讀取完成之后讀取。
請注意,如果沒有同步原語,很難知道什么時候可以完成myuselessvolatilefieldthatcanbestatic
:-),但是:
while (true)
{
var useless = myuselessvolatilefieldthatcanbestatic;
var iwanttoknow = thefieldiwanttoread;
// Some code goes here
}
現在至少你可以使用你的while (true)
:-)
如果要讀取最新的可用值,則應使用Interlocked.CompareExchange(ref bar, null, null)
。 檢查null只是為了滿足CompareExchange簽名(如果bar
為null
,則將其設置為null
)。 這將為您提供執行時CPU中可用的最新值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.