我有多个线程访问变量。我知道如何编写自旋锁并使用Threading.Interlocked方法来增加等变量。
但是,我想执行相当于:
a = Math.Min(a, b)
or
a = a | 10
...但没有使用关键部分。这可能吗?我知道第二行在汇编程序中是可行的,但是没有Interlocked.Or方法。
答案 0 :(得分:2)
如果你没有预料到很多争论那么可能是这样的? (如果可能存在很多争用,那么普通锁可能会更有效。)
int original; // assuming here that a is an int
do
{
original = a;
} while (Interlocked.CompareExchange(ref a, original | 10, original) != original)
答案 1 :(得分:2)
以下是模拟互锁操作的一般模式。
public static T InterlockedOperation<T>(ref T location, T value)
{
T initial, computed;
do
{
initial = location;
computed = op(initial, value); // initial | value
}
while (Interlocked.CompareExchange(ref location, computed, initial) != initial);
return computed;
}
min操作是一个完全不同的故事。这里的问题是有两个内存位置在起作用。此外,我们只对阅读它们感兴趣。这意味着我们真的只需要担心内存屏障问题。使用volatile
装饰字段,或在计算分钟前对Thread.MemoryBarrier
进行显式调用。
修改:我错过了将min操作的结果分配给a
的事实。您实际上可以使用我在上面定义的模式,而不是computed = initial | value
执行computed = initial < value ? initial : value
。其他一切都保持不变。