여기에 많은 질문이 있습니다. 한 번에 하나씩 고려 :
참조 할당은 원자 적이므로 Interlocked.Exchange (ref Object, Object)가 필요한 이유는 무엇입니까?
참조 할당은 원자 적입니다. Interlocked.Exchange는 할당을 참조 만하는 것이 아닙니다. 변수의 현재 값을 읽고 이전 값을 숨기고 새 값을 변수에 할당합니다.이 모든 것이 원자 적 연산입니다.
제 동료는 일부 플랫폼에서 참조 할당이 원자 적이라는 것이 보장되지 않는다고 말했습니다. 제 동료가 맞습니까?
아니요. 참조 할당은 모든 .NET 플랫폼에서 원 자성이 보장됩니다.
제 동료는 거짓 전제에서 추론하고 있습니다. 그것은 그들의 결론이 틀렸다는 것을 의미합니까?
반드시 그런 것은 아닙니다. 동료가 나쁜 이유로 좋은 조언을 줄 수 있습니다. Interlocked.Exchange를 사용해야하는 다른 이유가있을 수 있습니다. 잠금없는 프로그래밍은 엄청나게 어렵고 현장 전문가가지지하는 잘 확립 된 관행에서 벗어나는 순간 잡초에 빠져 최악의 경쟁 조건에 처하게됩니다. 저는이 분야의 전문가도 아니고 귀하의 코드에 대한 전문가도 아니므로 어떤 식 으로든 판단을 내릴 수 없습니다.
"휘발성 필드에 대한 참조는 휘발성으로 처리되지 않습니다"라는 경고를 생성합니다. 이에 대해 어떻게 생각해야합니까?
이것이 일반적인 문제인 이유를 이해해야합니다. 그러면이 특정 경우에 경고가 중요하지 않은 이유를 이해할 수 있습니다.
컴파일러가이 경고를 표시하는 이유는 필드를 휘발성으로 표시한다는 것은 "이 필드가 여러 스레드에서 업데이트 될 것입니다.이 필드의 값을 캐시하는 코드를 생성하지 말고 모든 읽기 또는 쓰기를 확인하십시오. 이 필드는 프로세서 캐시 불일치를 통해 "시간상 앞뒤로 이동"되지 않습니다.
(이미 모든 것을 이해하고 있다고 가정합니다. 휘발성의 의미와 프로세서 캐시 시맨틱에 미치는 영향에 대해 자세히 이해하지 못한 경우 작동 방식을 이해하지 못하고 휘발성을 사용해서는 안됩니다. 잠금없는 프로그램 프로그램이 올바른지 확인하기가 매우 어렵습니다. 프로그램이 작동하는 방식을 이해하고 있기 때문에 우연히 옳지 않은지 확인하십시오.)
이제 해당 필드에 ref를 전달하여 휘발성 필드의 별칭 인 변수를 만든다고 가정합니다. 호출 된 메서드 내에서 컴파일러는 참조가 휘발성 의미를 가져야한다는 것을 알 이유가 전혀 없습니다! 컴파일러는 휘발성 필드에 대한 규칙을 구현하지 못하는 메서드에 대한 코드를 쾌활하게 생성하지만 변수 는 휘발성 필드입니다. 그것은 잠금없는 논리를 완전히 망칠 수 있습니다. 휘발성 필드는 항상 휘발성 의미론으로 액세스 된다는 가정이 항상 있습니다. 때로는 그것을 휘발성으로 취급하고 다른 시간에는 취급하지 않습니다. 항상 일관성 이 있어야합니다. 그렇지 않으면 다른 액세스에 대한 일관성을 보장 할 수 없습니다.
따라서 컴파일러는 신중하게 개발 한 잠금없는 논리를 완전히 엉망으로 만들 것이기 때문에이 작업을 수행 할 때 경고를 표시합니다.
물론 Interlocked.Exchange 는 휘발성 필드를 예상하고 올바른 작업을 수행하도록 작성되었습니다. 따라서 경고는 오해의 소지가 있습니다. 나는 이것을 매우 후회한다. 우리가해야 할 일은 Interlocked.Exchange와 같은 메서드의 작성자가 "참조를 취하는이 메서드는 변수에 휘발성 의미를 적용하므로 경고를 억제"라는 속성을 메서드에 넣을 수있는 메커니즘을 구현하는 것입니다. 아마도 향후 버전의 컴파일러에서 그렇게 할 것입니다.