"인증서"는 무엇입니까?
volatile
키워드 에 대한 기사를 읽었 지만 올바른 사용법을 알 수 없습니다. C #과 Java에서 무엇을하는지 말씀해 주시겠습니까?
C #과 Java 모두 "인증서"는 변수 자체의 값이 프로그램 자체의 범위 밖에서 변경 될 수 있으므로 변수의 값을 캐시에 저장하는 것을 컴파일러에 알려줍니다. 그런 다음 컴파일러는 변수가 "제어 범위를 벗어나"변경 될 문제를 해결합니다.
이 예제를 고려하십시오.
int i = 5;
System.out.println(i);
컴파일러는 다음과 같이 5를 인쇄하도록 최적화 할 수 있습니다.
System.out.println(5);
그러나 오류있는 경우 오류 i
가 있습니다. 다른 버전은 i
6으로 변경 되면 최적화 된 버전은 여전히 5를 인쇄합니다.
volatile
키워드는 최적화 및 캐싱을 방지하며, 따라서 변수가 다른 경우에 의해 변경 될 수있는 경우 유용합니다.
인증서이 인증서 변수에 어떤 영향을 미치는지 이해 유효성이 있는지 여부 변수가 인증서가 아닌 경우 어떻게 이해하는 것이 중요합니다.
- 변수는 비 인증서
두 개의 경우 A & B가 비 인증서 변수에 액세스 할 때 각은 변수의 로컬 사본을 로컬 캐시에 유지합니다. 로컬 캐시에서 A가 수행 한 변경 내용은 내용은 표시되지 않습니다.
- 변수는 인증서
변수가 인증서로 선언됩니다. 즉, 일반적은 주 메모리에서 직접 읽지 않는 한 변수의 값을 신뢰합니다.
어디에 변수를 인증서로 지정합니까?
많은 수도가 액세스 할 수있는 변수가 있고 프로그램의 다른 프로그램 / 프로세스 / 프로세스에서 값을 업데이트하는 모든 값 외부가 해당 변수의 최신 업데이트를 얻으려고 할 때.
인증서 키워드는 모두 자바와 C #에서 다른 의미를 가지고 있습니다.
자바
로부터 Java 언어 사양 :
필드는 인증서로 선언 될 수 있으며,이 경우 Java 메모리 모델은 모든 경우가 변수에 대해 일관된 값을 볼 수 있습니다.
씨 #
휘발성 키워드 에 대한 C # 참조에서 :
휘발성 키워드는 운영, 하드웨어 또는 동시 실행되는 프로그램과 같은 프로그램에서 필드를 나타냅니다.
. 인증서 필드의 읽기는 의미를 얻습니다 . 즉, 인증서 변수에서 읽은 메모리는 다음 메모리를 읽기 전에 발생합니다. 컴파일러가 재정렬을 수행하는 것을 차단하고 하드웨어가 필요로하는 경우 (약한 순서의 CPU), 특수 명령을 사용하여 인증서 이후에 발생하지만 추론 적으로 초기 시작되거나 CPU가 읽을 수있는 모든 읽기를 하드웨어가 플러시 하도록합니다. 초기에 조기에 발생하는 폐기 시점 사이에 투기 적 부하가 발생하지 않도록 방지합니다.
필드 인증서의 쓰기에는 릴리스 시맨틱이 있습니다. 이는 모든 이전 메모리 쓰기가 다른 프로세서에 표시 될 때까지 인증서 변수에 대한 모든 메모리 쓰기가 지연 보장됩니다.
다음 예제를 고려하십시오.
something.foo = new Thing();
경우 foo
클래스의 멤버 변수이고, 다른 CPU에 쓰기에 의해 사용 된 개체 인스턴스에 액세스 할 수 있습니다 something
. 이러한 값이 표시 될 수 있습니다. foo
변화를 하기 전에 의 메모리를 생성 할 Thing
수 있습니다. 이것은 "약하게 정렬 된 메모리"라는 의미입니다. 컴파일러가 생성자에 모든 상점을 가지고있는 경우에도 보관 수 있습니다 foo
. 경우 foo
입니다 volatile
후하는 가게 foo
릴리스 의미를 가질 것이며, 보증은 쓰기 하드웨어 전에 쓰기의 모든 것을에 foo
쓰기가 허용하기 전에 다른 프로세서에 볼 수 있습니다 foo
발생할 수 있습니다.
쓰기 foo
순서가 너무 나빠질 수 있는 방법은 무엇입니까? 캐시 라인 보유 foo
가 캐시에 있고 생성자의 저장소가 캐시를 누락 한 경우 캐시 누락에 대한 쓰기보다 훨씬 빨리 저장소가 완료 될 수 있습니다.
인텔의 (끔찍한) Itanium 아키텍처는 메모리를 약하게 주문했습니다. 원래 XBox 360에 사용 된 프로세서의 메모리가 약합니다. 널리 사용되는 ARMv7-A가 포함 된 ARM 프로세서는 메모리를 약하게 주문했습니다.
잠금과 같은 것들이 본질적으로 동시에 의미를 보지 해제하는 것과 동일한 전체 메모리 장벽을 수행하기 때문에 개발자들은 이러한 데이터 경쟁을 못합니다. 잠금을하기 전에하기 전에 잠금의로드를 추론 할 때까지 사용할 수 있습니다. 잠금 해제에서 저장을 지연시킬 수 있습니다.
보다 완전한 예는 "이중 체크 잠금"패턴입니다. 이 패턴의 목적은 객체를 지연하기 위해 항상 잠금을 초기화하지 않는 것입니다.
위키 백과에서 n
public class MySingleton {
private static object myLock = new object();
private static volatile MySingleton mySingleton = null;
private MySingleton() {
}
public static MySingleton GetInstance() {
if (mySingleton == null) { // 1st check
lock (myLock) {
if (mySingleton == null) { // 2nd (double) check
mySingleton = new MySingleton();
// Write-release semantics are implicitly handled by marking mySingleton with
// 'volatile', which inserts the necessary memory barriers between the constructor call
// and the write to mySingleton. The barriers created by the lock are not sufficient
// because the object is made visible before the lock is released.
}
}
}
// The barriers created by the lock are not sufficient because not all threads will
// acquire the lock. A fence for read-acquire semantics is needed between the test of mySingleton
// (above) and the use of its contents.This fence is automatically inserted because mySingleton is
// marked as 'volatile'.
return mySingleton;
}
}
이 예에서 MySingleton
생성자의 저장소는 .NET에 저장되기 전에 다른 프로세서에 표시되지 않을 수 있습니다 mySingleton
. 이 경우 mySingleton을 들여다 보는 다른 스레드는 잠금을 획득하지 않으며 반드시 생성자에 대한 쓰기를 선택하지 않습니다.
volatile
캐싱을 방지하지 않습니다. 그것이하는 일은 다른 프로세서가 쓰는 순서를 보장하는 것입니다. 스토어 릴리스는 보류중인 모든 쓰기가 완료 될 때까지 스토어를 지연시키고 관련 라인이 캐시 된 경우 캐시 라인을 버리거나 다시 쓰도록 다른 프로세서에 알리는 버스주기가 발행됩니다. 로드 획득은 추측 된 모든 읽기를 플러시하여 과거의 오래된 값이되지 않도록합니다.
Java에서 "휘발성"은 변수가 동시에 여러 스레드에서 사용될 수 있음을 JVM에 알리는 데 사용되므로 특정 공통 최적화를 적용 할 수 없습니다.
특히 동일한 변수에 액세스하는 두 개의 스레드가 동일한 시스템의 별도 CPU에서 실행되는 상황입니다. 메모리 액세스가 캐시 액세스보다 훨씬 느리기 때문에 CPU가 보유한 데이터를 적극적으로 캐시하는 것은 매우 일반적입니다. 즉, 데이터가 CPU1에서 업데이트 되면 캐시가 자체를 지울 때가 아니라 즉시 모든 캐시와 주 메모리를 거쳐야하므로 CPU2가 업데이트 된 값을 볼 수 있습니다 (다시 모든 캐시를 무시 함).
비 휘발성 데이터를 읽을 때 실행중인 스레드는 항상 업데이트 된 값을 얻거나 얻지 못할 수 있습니다. 그러나 객체가 휘발성이면 스레드는 항상 최신 값을 가져옵니다.
참고 URL : https://stackoverflow.com/questions/3430757/what-is-the-volatile-keyword-used-for
'IT' 카테고리의 다른 글
응용 프로그램을 릴리스하기 전에 NSLog를해야하고 전에? (0) | 2020.07.21 |
---|---|
iOS (iPhone, iPad, iPodTouch) 실시간 콘솔 로그 터미널보기 (0) | 2020.07.21 |
페이지를 새로 고치지 않고 URL 변수 제거 (0) | 2020.07.21 |
사용자가 ASP.NET MVC에서 HTML을 입력하도록 허용 -ValidateInput 또는 AllowHtml (0) | 2020.07.21 |
처음으로 다섯 문자를 얻는 방법 (0) | 2020.07.21 |