2014-06-19 4 views
8

C# 휘발성 클래스를 이해하려고합니다.Volatile.Read/Write에 대한 이해

이 읽었 같이

  • Volatile.Write 메소드 호출 시점에 가 기록 될 위치의 값을 강제로. 또한 이전의 모든 프로그램 주문 로드 및 저장은 Volatile.Write 호출 전에 발생해야합니다.

  • Volatile.Read 메서드는 호출 할 때 에서 읽을 위치의 값을 강제로 지정합니다. 또한 이후 프로그램 주문로드에서는 을로드하고 Volatile.Read를 호출 한 후 저장해야합니다. m_flag에 쓰기를 시작하기 전에

    internal sealed class ThreadsSharingData {  
        private Int32 m_flag = 0; 
        private Int32 m_value = 0; 
        // This method is executed by one thread 
        public void Thread1() {   
         // Note: 5 must be written to m_value before 1 is written to m_flag 
         m_value = 5; 
         Volatile.Write(ref m_flag, 1);   
        } 
    
        // This method is executed by another thread 
        public void Thread2() {   
         // Note: m_value must be read after m_flag is read 
         if (Volatile.Read(ref m_flag) == 1) 
         Console.WriteLine(m_value);   
        }  
    } 
    

    CPU가 Volatile.Write(ref m_flag, 1); 전에 명령을 기다립니다 :

그의 경우에 의미인가?

스레드 동기화에 도움이되는 방법은 무엇입니까?

+1

약한 메모리 모델이있는 프로세서에서만 의미가 있습니다. ARM 코어 만 남았습니다. 적절한 동기화를위한 것이 아니라 * 동기화없이 스레드 안전 코드를 작성하는 것은 매우 진보 된 개념입니다. 그렇지 않으면 [이 질문] (http://stackoverflow.com/questions/15039188/volatile-vs-volatileread-write)에서 이미 잘 설명되어 있습니다. –

답변

4

CPU가 명령을 기다린 후 Volatile.Write (ref m_flag, 1); m_flag에 쓰기 시작하기 전에?

Eeeh, 다소. 구에 더 좋은 방법은이 : 다른 스레드가 1 m_flag 세트를 본다면, 그들은 또한 5

m_value 세트를 볼 수 있다는 보장 그리고 어떻게이 스레드를 동기화하는 데 도움이된다?

나는 그것이 동기화에 도움이된다고 말하지 않겠지 만 정확함을 얻는데 도움이된다.

휘발성 읽기/쓰기를 사용하지 않는 경우 컴파일러/런타임/CPU가 Thread1 메소드의 두 명령어를 재정렬 할 수 있으며 프로그램은 0, 5 또는 아무 것도 인쇄 할 수 없습니다 조금도.

휘발성 읽기/쓰기로 프로그램은 5 또는 아무 것도 인쇄하지 않지만 은 결코입니다. 의도 한 동작은 무엇입니까?

3

어떻게하면 스레드 동기화에 도움이됩니까?

명령이 실행되는 순서를 설정하는 의미에서 스레드 동기화에 도움이되지 않습니다. 이를 통해 동시 스레드가 특정 순서가 프로그램 논리에 중요 할 때 특정 순서로 메모리의 값 변경을 관찰 할 수 있습니다.

m_flag에 쓰기를 시작하기 전에 [Volatile.Write(ref m_flag, 1);]보다 먼저 명령을 기다리는가?

아니요, m_value에 쓰는 명령이 이미 실행되었습니다. 그러나 그 결과는 CPU 코어 외부에서 볼 수 없습니다. 특히, 다른 코어에서 실행중인 스레드는 m_value에서 이후에 이전 값을 읽을 수 있습니다. 실행 한 명령은 5입니다. 이는 새 값이 메모리가 아닌 CPU 캐시에있을 수 있기 때문입니다.

당신이

m_value = 5; 
m_flag = 1; 

대신 Volatile.Write(ref m_flag, 1)의 다른 코어는 다른 순서로 쓰기를 볼 수 있습니다 작성하는 경우 : 먼저이 m_flag1가 된 것을보고, 후에는 m_value5이 된 것을 볼 것이라는 것이다. 다른 스레드에서 m_flag 값을 사용하여 m_value의 유효성을 판단하면 논리가 손상되었을 수 있습니다. 예를 들어 Thread2은 때때로 0을 인쇄합니다.