在 C# 7 的元组之前,交换两个变量的标准方法如下:
var foo = 5;
var bar = 10;
var temp = foo;
foo = bar;
bar = temp;
但现在我们可以使用
(foo, bar) = (bar, foo);
它在一条线上,而且更漂亮。但它是线程安全的吗——交换是原子完成的,还是这只是多步骤操作之上的糖衣?
“不,基本上”。
The ValueTuple<...>
family 是可变的值类型,这使得它变得复杂。年龄较大的Tuple<...>
family 是不可变的引用类型; “不可变”很重要,因为它意味着它不会更改各个字段 - 它正在创建一个新对象all价值。 “参考类型”很重要,因为这是一个单一的参考交换is线程安全,因为您无法获得“撕裂的引用”。它在其他方面不是线程安全的:无法保证排序或寄存器等。
但与ValueTuple<...>
甚至那也消失了。因为它是可变类型,所以很可能实现为多个ldloca
/ld...
/stfld
指令,所以even if值类型不大于 CPU 宽度,不能保证它全部被写入单个 CPU 指令中 - 几乎肯定不会。在“返回一个值,分配整个事物”场景中might如果足够小,则可以是单个 CPU 指令,但也可能不是!为了让它变得更加复杂,此外对于可变字段方法,有also自定义构造函数 - 但它们最终仍将写入相同的内存位置(对于值类型,传递目标托管引用into构造函数,而不是传递的构造值out).
语言或运行时不保证元组的原子性;他们只对引用和某些原语做出保证 - 另外,即使是: 线程安全是lot不仅仅是原子性。
最后,它会also取决于目标CPU;显然是一个 2-int 元组cannot在 32 位 CPU 上是原子的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)