如何检测Interlocked.Add中的溢出(或下溢)

时间:2016-02-11 10:30:57

标签: c# .net multithreading interlocked

我想使用Interlocked.Add方法,因为intlong的速度更快。我有其他类型的代码:

short x = Sum(source, range.Item1, range.Item2);
checked
{   
    lock (syncRoot)
        result += x;                                          
} 

但是我发现Interlocked没有处理溢出。如何确定发生上溢或下溢? x可以是正面的,也可以是负面的。

var x = Sum(source, range.Item1, range.Item2);
Interlocked.Add(ref result, x);
bool overflow = ...
if (overflow)
   throw new OverflowException();

我在MSDN上找到了以下提示,但不知道如何实施此检查:

  

此方法通过包装来处理溢出条件:如果值为   location1是Int32.MaxValue,值是1,结果是   Int32.MinValue;如果value为2,则结果为(Int32.MinValue + 1);和   所以没有例外。

1 个答案:

答案 0 :(得分:1)

Interlocked.Add返回新值。如果新值小于旧值,则发生溢出。问题是你无法以这种方式获得旧值。

您可以使用CAS loop以原子方式读取旧值,检查溢出并以原子方式写入新值。

请注意,根本没有锁定互锁操作的比例。互锁操作仅仅是硬件锁。它们在绝对意义上更快,并且不会受到争用的影响。但是,以高频率执行此操作将无法从多个CPU中受益。