如何在互锁中添加中检测溢出(或下溢)

本文关键字:溢出 下溢 检测 添加 | 更新日期: 2023-09-27 18:34:07

我想使用Interlocked.Add方法,因为它对intlong更快。我有以下用于其他类型的代码:

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

但我发现联锁不处理溢出。如何确定发生溢出或下溢? x可以是正数,也可以是负数。

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

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

此方法通过包装来处理溢出条件:如果值在 位置 1 是 Int32.MaxValue,值为 1,结果是 Int32.MinValue;如果值为 2,则结果为 (Int32.MinValue + 1);和 等等。不会引发任何异常。

如何在互锁中添加中检测溢出(或下溢)

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

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

请注意,锁和互锁操作都无法缩放。联锁操作只是硬件锁。它们在绝对值上速度更快,并且不会受到争用的影响。但是以高频率执行此操作根本不会从多个 CPU 中受益。