2014-12-19 2 views
0

카운터 및/또는 개체 업데이트에 적합한 Parallel.ForEach loop with thread-local variables 실행에 대한 Microsoft의 지침을 읽었습니다. 내 질문에 비록 로컬 부울 변수를 다룰 때 필요합니다. 다음 코드를 살펴 보자 (그냥 샘플의 실제 코드는 훨씬 더 수행) :스레드 로컬 부울이있는 Parallel.ForEach 루프

public bool ParallelForEachLoopWithThreadLocalBoolVariable(IEnumerable<string> items) 
{ 
    bool doWork = false; 
    Parallel.ForEach<string, bool>(items, 
            () => false, 
            (match, loop, madeChange) => 
            { 
             if (match == "valid") 
             { 
              madeChange = true; 
              ProcessMatch(match); 
             } 
             return madeChange; 
            }, 
            (changed) => doWork = changed 
            ); 
    return doWork; 
} 

public bool ParallelForEachLoop(IEnumerable<string> items) 
{ 
    bool doWork = false; 
    Parallel.ForEach(items, match => 
        { 
         if (match == "valid") 
         { 
          doWork = true; 
          ProcessMatch(match); 
         } 
        }); 
    return doWork; 
} 

내 궁극적 인 목표는 ProcessMatch() 방법에서 수행 된 작업을 확산하고 전체 작업했는지를 나타내는 플래그를 반환하는 것입니다 어떤 차이를 만들었습니다. ParallelForEachLoopWithThreadLocalBoolVariable은 각 파티션에 부울 값을 할당하고 작업을 수행 할 마지막 파티션이 false로 끝나는 경우 잘못된 해석으로 끝날 수 있다고 생각하므로 ParallelForEachLoop 메서드로 이동하는 경향이 있습니다 (예 : match! = "valid"). . 로컬 변수 doWorkParallelForEachLoop 메서드의 다중 스레드에 의해 액세스되는 경우 예외가 발생할 수 있습니다. 조건이 충족되면 doWork를 한 번만 설정해야합니다. 반복 루프 전체에서 한 번만 발생하더라도 (각 유효한 일치에 대해 ProcessMatch을 실행해야합니다.) 내 두려움은 정당한가? 일부 시나리오에서 작동하지 않을 수도 있다는 걱정없이 ParallelForEachLoop 기능을 사용할 수 있습니까? 당신은 예외가 1을 발생하지받을 않습니다 변수 (변수 하지 속성 주)에 유효한 값을 지정하는 모든

답변

1

먼저, 그래서 두번째 방법에 대한 관심이 유효하지 않습니다.

스레드 로컬 변수는 리소스를 잠글 필요없이 비 원자 연산 ("그 동안"다른 일이 발생할 수 있고 결과가 변경 될 수있는 작업)을 수행 할 수 있으므로 다른 작업을 덜 자주 수행 할 수 있습니다 마지막 블록에서) 해당 작업을 잠그고 결과를 집계하십시오. 그러나 bool에 값을 할당하는 것은 원자 적 연산이므로 로컬 변수를 사용할 필요가 없습니다. MSDN 예제에서는 원자가 아닌 +=을 정수로 묶어 잠그거나 다른 스레드가 값을 왼쪽으로 수정하지 않도록 예제에서와 같이 로컬 변수를 사용해야합니다. 새 결과가 할당되기 전에 +=

요약하면 두 번째 버전을 사용하십시오.


1 : 변수에 값을 할당하는 것은, 내가 "추측 당신이 Constrained Execution Region

+0

감사에서 할 수있는 몇 가지 중 하나입니다 ... 부울에 값을 할당하는 것은입니다 원자 적 연산 "이 내가 찾고있는 것이다 (변수에 값을 할당하는 것이 예외를 던지지 않는다는 확인과 함께). 다시 한 번 감사드립니다! – Nir

+0

대부분의 값 유형에는 원자 할당이 있습니다. 내가 아는 유일한 것은 32 비트 플랫폼에서 실행되는 'long'입니다. 그러나 ['Interlocked.Read'] (http://msdn.microsoft.com/en-us/library/system.threading.interlocked.read (v = vs.110) .aspx)와 다른 '연동 '함수를 사용하면 원 자성을 부여 할 수 있습니다. –