В коде, как показано ниже, если Proc1 и Proc2 выполняются одновременно на разных процессорах, возможно ли, чтобы ThingVal2 получил значение, отличное от 5 (например, ноль)?Требуется ли защита памяти (.net x86 или x64) при разыменовании полей?
Class SimpleThing Public X As Integer Sub New(ByVal value As Integer) X = value End Sub End Class Class ConcurrencyTest Dim Thing1 As New SimpleThing(5) Dim Thing2 As New SimpleThing(0) Dim ThingRef As SimpleThing = Thing1 Dim ThingVal1, ThingVal2 As Integer Sub Proc1() Thing2.X = 5 Threading.Thread.MemoryBarrier() ThingRef = Thing2 End Sub Sub Proc2() ThingVal1 = Thing2.X ThingVal2 = ThingRef.X End Sub End Class
Я знаю, что в слабой модели как IA64, существует реальная возможность того, что Proc2 может видеть, как ThingRef поменяв, но не видеть поле Х Thing2, как, сделав это. Существует ли такой риск для приложения .Net, работающего на x86 или x64? Если Proc1 создал новый экземпляр SimpleThing, установите его поле X равным 5, а затем установите ThingRef, чтобы указать на него, этого было бы достаточно, чтобы избежать опасности, или было бы возможно, что новая вещь может быть выделена в строке кэша, которая был разделен с чем-то другим, к которому обратился поток Proc2?
Общая парадигма с многопоточным кодом состоит в том, чтобы построить неизменяемый объект и установить изменяемую ссылку, чтобы указать на него (возможно, с помощью Interlocked.CompareExchange). Всегда ли безопасно под x86/x64 читать неизменный тип без учета потоковой передачи или может вызвать проблемы? Если последний, что является предпочтительным способом в vb.net, чтобы гарантировать надежное поведение?
Кроме того, есть ли способ указать, что код должен выполняться таким образом, чтобы такие проблемы не могли возникнуть (например, ограничение выполнения одного ядра на чем-то вроде IA64, который иначе не мог бы гарантировать правильную работу)?
Неизменяемость гарантируется только в том случае, если значение может быть прочитано за один цикл. Int и bool попадают в эту категорию. Не так уверен в длине, и определенно не в строке. – SRM
@SRM: неизменный объект - это тот, который никогда не изменится после того, как ссылка станет доступной для кого-либо еще.Объект «SimpleThing» выше не является неизменным, потому что я пытаюсь точно спросить, что есть и не гарантируется в моделях памяти .net x86 и .net x64. – supercat