如何在互锁中添加中检测溢出(或下溢)
本文关键字:溢出 下溢 检测 添加 | 更新日期: 2023-09-27 18:34:07
我想使用Interlocked.Add
方法,因为它对int
和long
更快。我有以下用于其他类型的代码:
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 中受益。