2012-02-15 3 views
1

나는이 내 코드에서 다음과 같은 시나리오 (C# .NET을 4) :동기화 문제

내가 false로 초기화되는 부울 변수가 있습니다

bool b = false; 

가 지금은 스레드의 수를 인스턴스화 오전, 그들 각자는 b의 값을 읽을 필요가있다. b를 읽는 첫 번째 스레드는 값을 true로 변경하고 (일부 논리는 수행해야 함) 나머지는 아무것도 수행하지 않아야합니다. 값을 읽는 동안 'b'에 동기화 메커니즘을 사용해야합니까, 아니면 값을 true로 설정하는 동안 만 잠글 수 있습니까? 이 제 성능을 향상해야하지만, 나는 그것의 안전 ID를 궁금 ..

+0

어떤 언어입니까? – Tudor

답변

5

을 그래서 요구 사항은 다음과 같습니다 쓰레드가이해야 false 값을 보는 경우

  • 여러 스레드가 하나의 bool 변수
  • 읽기 스레드가 true 값을 보는 경우 다음 아무것도가이어야한다
  • 하나의 스레드 만 일이 없어야합니다 추가 작업
  • true으로 변경 및 수행 이 DoSomething을 실행하는 여러 스레드가 있고 의도가 있다는 것입니다 경우

    public class Example 
    { 
        private bool b = false; 
    
        public void DoSomething() 
        { 
        if (!b) 
        { 
         b = true; 
         DoExtraStuff(); 
        } 
        } 
    } 
    

    이것은 물론, 안전하지 : 같은 추가 작업

를 값을 변경하고 수행 할 BLE 그래서 코드가 보일 것이다 DoExtraStuff은 한 번만 실행해야합니다. 문제는 스레드가 b의 읽기 및 쓰기로 경쟁하게된다는 것입니다.

정말 읽고 읽고 쓸 필요가 b 원자. 이것은 lock 키워드를 사용하여 수행 할 수 있습니다.

public class Example 
{ 
    private bool b = false; 
    private object locker = new object(); 

    public void DoSomething() 
    { 
    bool trigger = false; 
    lock (locker) 
    { 
     if (!b) 
     { 
     b = true; 
     trigger = true; 
     } 
    } 

    if (trigger) 
    { 
     DoExtraStuff(); 
    } 
    } 
} 

Interlocked.CompareExhange 통해 CAS 동작을 이용하여 다른 패턴이있다. 불행히도 bool을 허용하는 과부하가 없지만 boolint으로 변경하려는 경우 다음 사항도 적용됩니다.

public class Example 
{ 
    private int b = 0; 

    public void DoSomething() 
    { 
    if (Interlocked.CompareExchange(ref b, 0, 1) == 0) 
    { 
     DoExtraStuff(); 
    } 
    } 
} 
+0

당신 말이 맞아요. 둘 이상의 스레드가 '! b'를 true로보고 if-block을 입력합니다. – Ajay

+0

예, 맞습니다. 이것이 올바른 버전입니다. 잘하면 OP가 주위에 온다 및 내 대답을 삭제할 수 있도록 허용 된 대답을 변경합니다. 나는 그가하고 싶은 것을 오해 한 것 같다. – Tudor

+0

@ 튜더 : 예, 오해하는 질문이 많이 발생합니다. 이 질문의 말씨는 조금 나아 졌을 수 있습니다. –