在如下代码中,如果 Proc1 和 Proc2 在不同的处理器上同时执行,ThingVal2 是否有可能获得 5 以外的值(例如零)?
类 SimpleThing 公共 X 作为整数 Sub New(ByVal value As Integer) X = 价值 结束子 结束类 类并发测试 Dim Thing1 作为新的 SimpleThing(5) Dim Thing2 作为新的 SimpleThing(0) 将 ThingRef 调暗为 SimpleThing = Thing1 将 ThingVal1、ThingVal2 调暗为整数 子程序1() 事物2.X = 5 Threading.Thread.MemoryBarrier() ThingRef = Thing2 结束子 子进程2() ThingVal1 = Thing2.X ThingVal2 = ThingRef.X 结束子 结束类
我知道在像 IA64 这样的弱模型中,Proc2 很有可能会看到 ThingRef 发生了变化,但没有看到 Thing2 的字段 X 发生了变化。在 x86 或 x64 上运行的 .Net 应用程序是否存在这种风险?如果 Proc1 创建了一个 SimpleThing 的新实例,将其 X 字段设置为 5,然后将 ThingRef 设置为指向它,这是否足以避免危险,或者是否有可能将新事物分配在缓存行上与 Proc2 线程访问过的其他东西共享?
多线程代码的一个常见范例是构造一个不可变对象并设置一个可变引用来指向它(可能使用 Interlocked.CompareExchange)。在 x86/x64 下读取不可变类型而不考虑线程是否总是安全的,还是会导致问题?如果是后者,在 vb.net 中保证可靠行为的首选方式是什么?
此外,是否有任何方法可以指定代码必须以不会发生此类问题的方式运行(例如,将执行限制在诸如 IA64 之类的单个内核上,否则无法保证正确运行)?