Interlocked.Increment 溢出会导致 .NET 运行时损坏吗?

Posted

技术标签:

【中文标题】Interlocked.Increment 溢出会导致 .NET 运行时损坏吗?【英文标题】:Can Interlocked.Increment overflow cause .NET runtime corruption? 【发布时间】:2016-02-22 16:29:48 【问题描述】:

Interlocked.Increment 的 MSDN 文档指出:

此方法通过包装处理溢出条件:if location = Int32.MaxValue, location + 1 = Int32.MinValue。不抛出异常。

位置 + 1”在这种情况下是什么意思?如果Increment 更改了 location 字段旁边的内存位置,这不会导致 .NET 运行时损坏,因为这个相邻位置可以是任何东西(对象引用、类元数据等)?

【问题讨论】:

在这种情况下,location 只是一个 int 变量的名称。所以说location + 1 只是一个普通的数学陈述。 location + 1 只是一个数学语句。 location = Int32.MaxValue 所以 location + 1 会溢出到Int32.MinValue 是的,这更有意义。 (我一直在阅读太多指针算术。)感谢大家的澄清! 这是一个非常平庸的名字,参数实际上是一个指针。因此“位置”。 C# 中的 ref 关键字确保在运行时生成指针。抖动直接将该方法转换为单个 CPU 指令,LOCK XADD 用于 x86 和 x64,不会发生运行时损坏。 我猜这个名字让我很反感,同时使用= 来表示相等而不是赋值。我想我可能遗漏了一些明显的东西。 【参考方案1】:

这只是意味着如果你想要增加的值已经等于Int32.MaxValue并且你增加一,而不是抛出错误,它返回Int32.MinValue

如果你这样做,会发生同样的事情

var value = Int32.MaxValue;
value += 1;

如果您明确希望抛出异常,请使用 checked 关键字

var value = Int32.MaxValue;
value = checked(value + 1);

【讨论】:

只是提到value = checked(Interlocked.Increment(ref value)); 确实如果 value 是 int.MaxValue 则抛出异常,它只是将它设置为 int.MinValue

以上是关于Interlocked.Increment 溢出会导致 .NET 运行时损坏吗?的主要内容,如果未能解决你的问题,请参考以下文章

如果 Interlocked.Increment 是原子的,为啥我应该使用 ++ 代替?

C#原子操作(Interlocked.Decrement和Interlocked.Increment)

使用Interlocked.Increment的C#对象池

SQL Server 中的 NEXT VALUE FOR @Sequence 的工作方式是不是与 C# 中的 Interlocked.Increment() 相同? [复制]

信号灯 ManualResetEvent 与 Interlocked.Increment 原子操作使

Interlocked介绍