옵션 1 : Interlocked
와 DateTime.ToBinary()
와 long
를 사용합니다. Interlocked가 이미 원자 적 업데이트를 보장하기 때문에 volatile
(실제로는 경고가 표시됩니다)이 필요하지 않습니다. 이 방법으로 DateTime의 정확한 값을 얻을 수 있습니다.
DateTime GetLastHit()
{
long lastHit = Interlocked.CompareExchange(ref _lastHit, 0, 0);
return DateTime.FromBinary(lastHit);
}
이것은 _lastHit의 값을 반환하고, 그것을 0 0 스왑 인 경우 (즉, 값 원자를 읽을 이외의 아무것도하지 않습니다) :
long _lastHit;
void Touch()
{
Interlocked.Exchange(ref _lastHit, DateTime.Now.ToBinary());
}
은 원자이를 읽을 수 있습니다.
단순히 변수가 휘발성으로 표시되지 않았기 때문에 읽기가 쉽지 않습니다. 따라서 후속 읽기는 캐시 된 값을 재사용 할 수 있습니다. 휘발성을 결합하면 & 연동 가능성이 여기 (나는 완전히 확실하지 않지만 연동되지 않은 쓰기가 비 연동 읽기를 수행하는 다른 코어에 의해 일관성없는 상태로 보일 수 없다고 생각합니다). 하지만 이렇게하면 두 가지 기술을 결합하여 경고와 코드 냄새가 날 것입니다.
옵션 2 : 자물쇠를 사용하십시오. 이 경우 인터록 방식이 더 효과적이기 때문에 이러한 상황에서는 바람직하지 않습니다. 하지만 당신은 올바른 유형을 저장할 수 있으며, 소폭 명확입니다 :
DateTime _lastHit;
object _lock = new object();
void Touch()
{
lock (_lock)
_lastHit = DateTime.Now;
}
당신은 도이 값을 읽기 위해 잠금 장치를 사용해야합니다! 덧붙여, 상호 배제 외에도 잠금은 캐시 된 값을 볼 수 없으며 읽기/쓰기를 재정렬 할 수 없도록합니다.
비표준 : volatile
으로 표시할지 여부는 선택하지 말고 그냥 값을 쓰십시오. 이것은 잘못된 것입니다 - 당신이 값을 읽어 본 적이 경우에도 32 비트 컴퓨터에 당신의 쓰기가 당신이 손상된 값을 얻을 같은 불운 방식으로 인터리브 수
Thread1: writes dword 1 of value 1
Thread2: writes dword 1 of value 2
Thread2: writes dword 2 of value 2
Thread1: writes dword 2 of value 1
Result: dword 1 is for value 2, while dword 2 is for value 1
저는 이것이 이전 질문이지만 CPU의 명령 실행 순서를 보장 할 수 없다고 생각하는 것을 어떻게 생각합니까? 약간 더 새로운 타임 스탬프를 오래된 것으로 교체하지 않는다는 것을 알고 계십니까? (우리는 여기서 나노 초를 말하고 있습니다.) –