Parallel.ForEach를 어떻게 제한 할 수 있습니까?


295

웹 페이지를 다운로드하는 Parallel.ForEach () 비동기 루프가 있습니다. 대역폭은 제한되어 있으므로 한 번에 x 페이지 만 다운로드 할 수 있지만 Parallel.ForEach는 원하는 웹 페이지의 전체 목록을 실행합니다.

Parallel.ForEach를 실행하는 동안 스레드 번호 또는 다른 제한기를 제한하는 방법이 있습니까?

데모 코드 :

Parallel.ForEach(listOfWebpages, webpage => {
  Download(webpage);
});

실제 작업은 웹 페이지와 관련이 없으므로 창의적인 웹 크롤링 솔루션은 도움이되지 않습니다.


@ jKlaus 목록이 수정되지 않으면 예를 들어 URL 세트 일뿐이므로 실제로 문제를 볼 수 없습니까?
Shiv

@Shiv, 충분한 시간이 주어지면 ... 실행 횟수를 세고 목록의 개수와 비교하십시오.
jKlaus

@jKlaus 무슨 말이 잘못 될까요?
Shiv

1
@jKlaus는 스레드로부터 안전하지 않은 요소 (정수)를 수정하고 있습니다. 그 시나리오에서는 작동하지 않을 것으로 예상됩니다. 반면에 OP는 스레드 안전 해야하는 것을 수정하지 않습니다.
Shiv

2
@jKlaus 다음은 Count . > dotnetfiddle.net/moqP2C를 올바르게 설정하는 Parallel.ForEach의 예입니다 . MSDN 링크 : msdn.microsoft.com/en-us/library/dd997393(v=vs.110).aspx
jhamm

답변:


564

매개 변수 MaxDegreeOfParallelism에 a를 지정할 수 있습니다 ParallelOptions.

Parallel.ForEach(
    listOfWebpages,
    new ParallelOptions { MaxDegreeOfParallelism = 4 },
    webpage => { Download(webpage); }
);

MSDN : Parallel.ForEach

MSDN : ParallelOptions.MaxDegreeOfParallelism


59
이 특별한 경우에는 적용되지 않을 수도 있지만 누군가 궁금해하고 유용하다고 생각되는 경우에 버릴 것이라고 생각했습니다. 여기서는 프로세서 수의 75 % (반올림)를 사용하고 있습니다. var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 1.0)) };
jKlaus

4
문서에서 찾아보아야하는 다른 사람을 저장하기 위해 값을 전달하는 것은 값을 -1지정하지 않는 것과 같습니다. "[값]이 -1이면 동시에 실행되는 작업 수에 제한이 없습니다."
stuartd

문서에서 명확하지 않습니다-MaxDegreeOfParallelism을 4로 설정하면 (예를 들어) 루프 반복의 1/4을 실행하는 4 개의 스레드가 있음을 의미하거나 (4 개의 스레드 라운드가 1 회 파견 됨) 각 스레드가 여전히 하나의 루프를 수행합니다 반복과 우리는 얼마나 많은 병렬 실행을 제한하고 있습니까?
Hashman

7
명확한 코어와 스레드는 같은 것이 아닙니다. CPU에 따라 코어 당 다른 수의 스레드가 있으며 대개 코어 당 2 개입니다. 예를 들어 코어 당 2 개의 스레드가있는 4 개의 코어 CPU가있는 경우 최대 8 개의 스레드가 있습니다. @jKlaus 코멘트를 조정하려면 var opts = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0)) };. 스레드와 코어로 연결 -askubuntu.com/questions/668538/…
TheMiddleMan

41

ParallelOptions를 사용하고 MaxDegreeOfParallelism을 설정하여 동시 스레드 수를 제한 할 수 있습니다.

Parallel.ForEach(
    listOfwebpages, 
    new ParallelOptions{MaxDegreeOfParallelism=2}, 
    webpage => {Download(webpage);});     

21

인스턴스에 Parallel.Foreach걸리는 다른 과부하를 사용 하고 동시에 실행되는 인스턴스 수를 제한하도록 ParallelOptions설정하십시오 MaxDegreeOfParallelism.


11

그리고 VB.net 사용자 (구문은 이상하고 찾기가 어렵습니다) ...

Parallel.ForEach(listOfWebpages, New ParallelOptions() With {.MaxDegreeOfParallelism = 8}, Sub(webpage)
......end sub)  
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.