2013-12-09 1 views
0

ManualResetEvent는 기본적으로 다른 스레드에 "계속할 신호를받을 때만 진행할 수 있습니다"라고 말하며 특정 조건이 충족 될 때까지 특정 스레드의 실행을 일시 중지하는 데 사용됩니다. 제가 궁금해하는 것은 왜 while 루프를 사용하여 우리가 원하는 것을 쉽게 얻을 수있을 때 ManualResetEvent입니까? 다음과 같은 상황을 고려ManualResetEvent 대 while 루프

public class BackgroundService { 

ManualResetEvent mre; 
public BackgroundService() { 
    mre = new ManualResetEvent(false); 
} 
public void Initialize() { 
    // Initialization 
    mre.Set(); 
} 

public void Start() { 
    mre.WaitOne(); 
    // The rest of execution 
} 
} 

public class BackgroundService { 

bool hasInitialized; 
public BackgroundService() { 

} 
public void Initialize() { 
    // Initialization 
    hasInitialized = true; 
} 

public void Start() { 
    while (!hasInitialized) 
    Thread.Sleep(100); 
    // The rest of execution 
} 
} 

다소 유사하다으로 ManualResetEvent는 while 루프보다 더 적합한 특정 상황이 있습니까?

+1

'ManualResetEvent'가 더 정확합니다. 루프가 최악의 경우에 대해 99ms를 잃을 수 있습니다. – Sinatr

+0

쓰레드는 while 루프에서 동일 할 것입니다. 다른 작업을 수행 할 수 없다는 것입니다. 다중 쓰레드를 가진 것처럼, 다음 일을 계속하기 위해 어떤 표시가 필요한 특정 영역이있을 수 있습니다. 스레드는 예를 들어, 결과를 일괄 처리하여 T1이 일괄 처리하고 신호를 발생시킨 다음 T2가 일괄 처리의 일괄 처리 삽입/처리를 수행 할 수 있습니다. 이는 단지 하나의 예일뿐입니다. 각 스레드는 무언가를하는 데 전념 할 것입니다. 단일 스레드는 성능이 좋지 않고 유지 보수성이 느려질 수 있습니다. –

+0

while 루프와의 스레드 동기화와 같은 것을 어떻게 달성합니까? manualresetevent로 간단하고 간단합니다. 당신은 또한 내가 생각하는 디자인 관점에서 당신의 필요에 맞는 것을 고려해야합니다. – Sameer

답변

3

ManualResetEvent가 while 루프보다 더 적합한 특정 상황이 있습니까?

물론입니다. 주된 이유는 대기 시간과 효율성입니다.

다시 실행을 시작하기 위해 스레드를 컨텍스트 스위칭하는 것은 상대적으로 비용이 많이 들며 잠자기 상태로 돌아갈 때 hasInitialized 변수에 응답하기 위해 평균 50ms가 소요됩니다. 그것이 전혀 응답한다고 가정 할 때. (당신은 명시적인 메모리 장벽이 없기 때문에 스레드가 실제로 변수에 대한 변경을 볼 수 없을 수도 있습니다. Thread.Sleep을 호출하면 메모리 장벽이 효과적으로 추가되지만 보장되지는 않습니다.) OS/CLR 수준의 동기화 프리미티브를 사용하면 스레드가 훨씬 빠르게 응답 할 수 있습니다.

0

제공된 신호를 사용하면 ManualResetEvent이 더 효율적입니다. 약 100 밀리 초 (즉, 초당 10 회) 후에 루프를 사용하면 다른 스레드는 실행을 중지해야 상태를 확인하는 스레드가 실행되어야하므로이 컨텍스트가 조건이 대부분 거짓이면 효율성이 떨어집니다.

하지만 뭔가 코드에서 매우 비위생적 인 냄새가납니다. 초기화 할 때 어떤 코드를 폴링했을까요? 초기화가 비동기 인 경우 이미 일부 알림 메커니즘이 있습니다. 호출이 완료되면 폴링이 필요하지 않습니다.