![]() |
1
159
这里有许多问题。一次考虑一个:
引用分配是原子的。互锁。交换不仅执行引用分配。它读取变量的当前值,隐藏旧值,并将新值赋给变量,所有操作都是原子操作。
不。引用分配保证在所有.NET平台上都是原子的。
不一定。你的同事可能会出于不好的原因给你一些好的建议。也许还有其他的原因,你应该使用interlocked.exchange。无锁编程是非常困难的,当你离开这个领域的专家们所拥护的成熟的实践时,你就会陷入困境,冒着最坏的竞争环境的危险。我既不是这个领域的专家,也不是你代码方面的专家,所以我不能以这种或那种方式做出判断。
你应该理解为什么这是一个普遍的问题。这将导致理解为什么在这种特殊情况下警告并不重要。 编译器发出此警告的原因是,将字段标记为volatile意味着“此字段将在多个线程上更新--不要生成缓存此字段值的任何代码,并确保此字段的任何读或写不会通过处理器缓存不一致“及时前后移动”。 (我想你已经了解了这一切。如果您没有对volatile的含义以及它如何影响处理器缓存语义的详细了解,那么您就不了解它是如何工作的,不应该使用volatile。无锁程序很难正确执行;请确保您的程序是正确的,因为您了解它的工作原理,而不是意外地正确执行。) 现在假设您通过向该字段传递一个引用来生成一个变量,该变量是易失性字段的别名。在被调用的方法中,编译器没有任何理由知道引用需要具有易失性语义!编译器将愉快地为未能实现易失性字段规则的方法生成代码,但是变量 是 不稳定的领域。这会完全破坏您的无锁逻辑;假设总是一个不稳定的字段 总是 使用易失性语义访问。有时把它当作易变的而不是其他时候,这是没有意义的;你必须 总是 保持一致,否则不能保证其他访问的一致性。 因此,当您执行此操作时,编译器会发出警告,因为它可能会彻底破坏您精心开发的无锁逻辑。 当然,互锁。交换 是 写的是期望一个不稳定的字段并做正确的事情。因此,该警告具有误导性。我对此非常遗憾;我们应该做的是实现某种机制,通过这种机制,类似interlocked.exchange的方法的作者可以在方法上放置一个属性,表示“这个采用ref的方法对变量强制执行易失性语义,因此取消警告”。也许在未来的编译器版本中,我们会这样做。 |
![]() |
2
9
要么你的同事搞错了,要么他知道一些C语言规范不知道的事情。 5.5 Atomicity of variable references 以下内容:
因此,您可以写入易失性引用,而不会有获取损坏值的风险。 当然,您应该注意如何决定哪个线程应该获取新的数据,以最大限度地降低一次多个线程这样做的风险。 |
![]() |
3
6
它会更改并返回原始值,这是无用的,因为您只想更改它,正如Guffa所说,它已经是原子的了。 除非一个探查器被证明是应用程序中的瓶颈,否则您应该考虑解除锁定,这样更容易理解和证明您的代码是正确的。 |
![]() |
4
2
Synchronization and Multiprocessor Issues 这意味着除了原子性之外,它还确保:
|
|
Robert King · Unity C#语法问题-转换位置 1 年前 |
![]() |
JBryanB · 如何从基本抽象类访问类属性 1 年前 |
|
law · 检查答案按钮的输入字符串格式不正确 2 年前 |
![]() |
i_sniff_ket · 在unity之外使用unity类 2 年前 |