【发布时间】:2021-06-03 21:49:11
【问题描述】:
以下示例来自MSDN。
public class ThreadSafe
{
// Field totalValue contains a running total that can be updated
// by multiple threads. It must be protected from unsynchronized
// access.
private float totalValue = 0.0F;
// The Total property returns the running total.
public float Total { get { return totalValue; }}
// AddToTotal safely adds a value to the running total.
public float AddToTotal(float addend)
{
float initialValue, computedValue;
do
{
// Save the current running total in a local variable.
initialValue = totalValue;
// Add the new value to the running total.
computedValue = initialValue + addend;
// CompareExchange compares totalValue to initialValue. If
// they are not equal, then another thread has updated the
// running total since this loop started. CompareExchange
// does not update totalValue. CompareExchange returns the
// contents of totalValue, which do not equal initialValue,
// so the loop executes again.
}
while (initialValue != Interlocked.CompareExchange(ref totalValue,
computedValue, initialValue));
// If no other thread updated the running total, then
// totalValue and initialValue are equal when CompareExchange
// compares them, and computedValue is stored in totalValue.
// CompareExchange returns the value that was in totalValue
// before the update, which is equal to initialValue, so the
// loop ends.
// The function returns computedValue, not totalValue, because
// totalValue could be changed by another thread between
// the time the loop ends and the function returns.
return computedValue;
}
}
不应该将 totalValue 声明为 volatile 以获得可能的最新值吗?我想如果您从 CPU 缓存中获取脏值,那么对 Interlocked.CompareExchange 的调用应该负责获取最新值并导致循环重试。 volatile 关键字可能会节省一个不必要的循环吗?
我猜想 volatile 关键字并不是 100% 必要的,因为该方法具有采用不支持 volatile 关键字的 long 等数据类型的重载。
【问题讨论】:
标签: c# cpu-architecture volatile lock-free compare-and-swap