2012-06-01 2 views
7

나는 재귀적인 문제가있다. 소비자는 트리의 각 레벨에서 어떤 일을하고 트리를 되풀이하여 다음 단계에서 똑같은 작업을 수행해야한다.생산자가 소비자 일 때 생산자/소비자 패턴에서 blockingcollection을 사용하는 방법 - 어떻게 끝내나요?

이것을 병렬로 실행하려면 ConcurrentBag/BlockingCollection 등을 사용하고 싶습니다. 이 시나리오에서 대기열의 사용자는 대기열의 생성자이기도합니다!

내 문제는 다음과 같습니다. BlockingCollection을 사용하여 항목을 큐에서 꺼내고 새 큐를 큐에 넣을 수있는 아주 간단한 foreach 논리를 작성할 수 있습니다. 큐가 비어있을 때 블로킹 콜렉션이 올바르게 블록화되어 새로운 작업이 생성 될 때까지 기다립니다. 다른 소비자 중 하나.

하지만 모든 소비자가 차단하는지 어떻게 알 수 있습니까?!

CompleteAdding()에 대해 알고 있지만 실제로는 완성 된 유일한 시간은 모든 제작자가 제작을 완료하고 대기열이 비어있는 경우입니다. 그리고 모두 차단되므로, 아무도 CompleteAdding()을 설정할 수있는 "무료"가 없습니다. 이걸 감지 할 수있는 방법이 있습니까? (블로킹 할 때 발생하는 이벤트 일 수도 있고 블럭을 해제 할 때 다시 발생하는 이벤트 일 수도 있습니다.)

foreach를 사용하지 않고 수동으로 처리 할 수 ​​있지만 while (! complete) 루프를 수동으로 처리하고 TryTake를 사용합니다. 수동으로 잠자기해야하는데, 이는 비효율적 인 것으로 보인다 (블록 콜렉션 대 최초의 동시 콜렉션 대 모든 이유!) 루프를 통과 할 때마다 TryTake가 false이면 Idle 플래그를 설정할 수있다. 대기열이 비어 있고 모든 스레드가 유휴 상태 인 경우 마스터 검사를 수행하고 전체 플래그를 설정합니다. 그러나 다시 이것은 kludgy로 보입니다.

직감은 Blocking Collection을 사용하여이를 수행 할 수있는 방법이 있음을 말하고 있지만 실제로는 그럴 수 없습니다.

어쨌든, 누구는 소비자가 생산자와 모든 블록은 MSDN에서이 링크는 당신을 도울 수 내가 생각

+1

좋은 질문입니다. 외부의 깃발이나 이벤트가있는 것은 경주 조건에 익숙해 보입니다. –

+0

프로세서 (결합 된 소비자/생산자)는 많은 주를 보유하고 있거나 많은 리소스가 필요합니까? 각각의 작업이 하나의 반복만을 수행하는 '작업'을 만드는 관점에서 문제를 다시 제기 할 수 있습니까? –

+0

@Damien_The_Unbeliever : 예, 단일 반복 작업을 수행 할 수 있습니다. 실제로는 이미 작동하지만 제작자/고객 패턴을 사용하려고합니다. 이는 향후 작업자 역할이 될 클라우드로 마이그레이션 될 수있는 코드이기 때문에 노력하고 있습니다. 동일한 방식으로 Azure Queue 스토리지를 사용하고 두 가지 구현간에 가능한 한 전체 로직을 유지하고 싶습니다. 그 시나리오에서 나는 작업자가 대기열이 완료 될 것임을 결정하기 위해 유휴 상태인지 확인해야하지만, 가능한 한 로컬에서 효율적이어야하는 것처럼 보입니다. - 또한 이것을 알아 내고 싶습니다. –

답변

-3

좋지 않을까 발표 할 때를 감지 할 수있는 경우에 대한 좋은 패턴을 가지고있다.

Reusable Parallel Data Structures and Algorithms

이 동시 시나리오에서 일부 데이터 구조를 처리하는 방법을 제공합니다.

+1

2007 년 데이터 구조는 4.0 동시 라이브러리에 대한 내 질문을 해결하지 않습니다. –

+0

그래서 4.0을 사용하여 직접 구현하십시오. 이것은 단지 지침 일뿐, "대답"이 아닙니다. – oarrivi

관련 문제