다음과 같은 코드에서 Proc1과 Proc2가 서로 다른 프로세서에서 동시에 실행되는 경우 ThingVal2가 5가 아닌 값 (예 : 0)을 가져올 수 있습니까?필드를 역 참조 할 때 메모리 장벽이 필요합니까 (.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의 필드 X를 볼 수있는 실제 가능성이 있다는 것을 알고있다. x86 또는 x64에서 실행되는 .Net 응용 프로그램에 대한 위험이 있습니까? Proc1이 SimpleThing의 새 인스턴스를 만든 경우 X 필드를 5로 설정 한 다음 ThingRef가이를 가리 키도록 설정하면 위험을 피하기에 충분하거나 새로운 것이 캐시 라인에 할당 될 가능성이 있습니다 Proc2 스레드가 액세스 한 다른 것과 공유 되었습니까?
멀티 스레드 코드를 사용하는 일반적인 패러다임은 불변 개체를 구성하고이를 가리 키도록 변경 가능한 참조를 설정하는 것입니다 (아마도 Interlocked.CompareExchange를 사용하여). 스레딩에 관계없이 불변 타입을 읽는 것이 x86/x64에서 항상 안전합니까? 아니면 문제를 일으킬 수 있습니까? 후자의 경우 신뢰할 수있는 동작을 보장하기 위해 vb.net에서 선호되는 방법은 무엇입니까?
또한 이러한 문제가 발생할 수없는 방식으로 코드를 실행해야한다고 지정하는 방법이 있습니까 (예 : 올바른 작동을 보장 할 수없는 IA64와 같은 단일 코어로 실행 제한).
값을 한 번만 읽으면 변경 불가능합니다. Int와 bool이 해당 카테고리에 속합니다. 길지는 않지만 확실히 문자열은 아닙니다. – SRM
@SRM : 불변 개체는 다른 사람이 참조를 사용할 수있게되면 변경되지 않습니다.위의 'SimpleThing'객체는 .net x86 및 .net x64 메모리 모델에서 보장되는 것과없는 것을 정확하게 묻기 때문에 변경 불가능하지 않습니다. – supercat