2012-02-28 2 views
1

현재 하나의 스레드에서 여러 스레드가 스레드 관리자의 큐에 무엇인가를 추가 할 때까지 기다리기 위해 ManualResetEvent를 사용 중입니다. 스레드 관리자가 수동 재설정 이벤트를 사용하여 신호를 받으면 추가 된 항목을 대기열에서 제외하고 추가 처리를 수행합니다. 내 유일한 문제는 여러 세트가 트리거되면 다른 대기열 항목이 처리되지 않는다는 것입니다. 여기에 내 해결 A 점의 큐 크기 조건을 추가하는 것입니다ManualResetEvent 크기가 다중 스레드를 기다리는 데 충분합니까?

while (IsThreadRunning) 
{ 
    // A: My workaround is to check if queue has item, if not then wait for other thread to set the event 
    if (DataQueue.Count <= 0) 
    { 
     ResetEvent.WaitOne(); 
    } 

    // B: At this point two thread added item to the queue and did ResetEvent.Set() twice. 
    if (DataQueue.Count > 0) 
    { 
     DataQueue.Dequeue(); 
    } 

    // Reset the event to avoid processor hog 
    ResetEvent.Reset(); 
} 

(점 B 참조). 데드락을 피하기 위해 다른 방법이 있습니까?

참고 : ManualResetEvent 사용에 대한 예제에서 제공되는 일반적인 시나리오에는 단일 스레드에서 이벤트를 기다리는 다중 스레드가 있지만 (ManualResetEvent.Set) 이벤트가 여러 스레드에서 트리거됩니다. 이 시나리오에 사용되는 다른 클래스가 있습니까?

+1

간단히 잠시 시간을 바꾸지 않는 이유는 무엇입니까? –

답변

1

대기열에있는 모든 항목을 처리 할 수 ​​있습니다 (있는 경우). 그런 다음 이벤트가 신호를받을 때까지 대기 할 수 있습니다.

이벤트가 신호를 받으면 즉시 재설정하십시오.

마지막 항목을 큐에서 처리 한 후 이벤트가 신호를 받으면 최악의 상황은 큐를 확인하면 비어있게됩니다.

while (IsThreadRunning) 
{ 
    while (DataQueue.Count > 0) 
    { 
    DataQueue.Dequeue(); 
    } 
    ResetEvent.WaitOne(); 
    ResetEvent.Reset(); 
} 
1

수동 재설정 이벤트를 지금 덤프하십시오. 어떤 종류의 이벤트도 사용하지 마십시오. 세마포와 잠금 장치를 사용하십시오. 푸시 메소드에서 대기열을 잠그고 객체를 대기열로 밀어 넣고 잠금 문 블록을 종료 한 다음 세마포 신호를 보냅니다. pop 메소드에서, 세마포어를 기다린 다음, 큐를 잠그고, 객체를 띄우고, lock 문 블록을 종료하십시오.

생산자 - 소비자 대기열을 실제로 집으로 만들고 싶다면이게 맞아요. 이미 작동하는 대기열을 원한다면 BlockingCollection 클래스를 살펴보십시오.

+0

이게 너니? http://www.dijksterhuis.org/using-semaphores-in-c/ – Nap

+0

@Nap - no. 큐 잠금과 세마포어 (큐가 제한되어 있다면 세마포어 2 개 사용)는 생산자 - 소비자 큐를 구현하는 'Computer Science 101'방법입니다. 개발자가 세마포 대신 이벤트를 사용하여 카운터가있는 동기화 메커니즘에 대한 정보를 얻는 방법을 알 수 없습니다. –

관련 문제