2017-01-24 2 views
0

다음 작업이 있습니다.이 변수는 합계 변수를 공유하며 결국 합계는 9이지만 3이됩니다. 해결 방법을 알려주십시오. 많은 감사합니다.C# 작업 변수 합계

int sum = 0; 
Task t1 = Task.Factory.StartNew(() => 
{ 
    sum = sum + Computation(); 
}); 
Task t2 = Task.Factory.StartNew(() => 
{ 
    sum = sum + Computation(); 
}); 
Task t3 = Task.Factory.StartNew(() => 
{ 
    sum = sum + Computation(); 
}); 

Task.WaitAll(t1, t2, t3); 
Console.WriteLine($"The sum is {sum}"); 

private static int Computation() 
{ 
    return 3; 
} 
+1

Computation() 코드를 공유 할 수 있습니까? – buffjape

+0

왜 여기서 작업을 사용하고 있습니까? – mason

+0

여기에 스레드 동기화 로직이 없습니까? 스레드를 수정하여 동기화 할 수 있습니까? –

답변

6

동시에 여러 스레드에서 동일한 필드를 작성하고 있기 때문입니다.

System.Threading의 Interlocked.Add를 사용하면 각 스레드가 동일한 순간에 변수를 쓰지 못하게됩니다.

int sum = 0; 
Task t1 = Task.Factory.StartNew(() => 
{ 
    Interlocked.Add(ref sum,Computation()); 
}); 
Task t2 = Task.Factory.StartNew(() => 
{ 
    Interlocked.Add(ref sum,Computation()); 
}); 
Task t3 = Task.Factory.StartNew(() => 
{ 
    Interlocked.Add(ref sum,Computation()); 
}); 

Task.WaitAll(t1, t2, t3); 
Console.WriteLine($"The sum is {sum}"); 
+0

좋아, 작동하지만 심판을 추가해야합니다 : Interlocked.Add (ref sum, Computation()); –

+0

그 호출에'ref'가 필요합니다. 원래의 것을 주목하면, 결과는 9 또는 6 일 가능성이 있습니다. 때때로 작동 할 수있는 것들은 안정적으로 실패 할 것이므로 고정되어있는 것보다 나쁩니다. –

+0

감사합니다. 그것이 개선 될 수 있다고 생각합니까? –

0

는 등 'T2'를 시작할 때까지 당신은 작업 'T1'이 완료 될 때까지 기다려야 코드를 말하지 않을, 그래서 모든 병렬로 실행합니다. 각 스레드는 "합"(처음에는 0)의 값을 읽고 3을 더합니다. 그래서 0 + 3 = 3. 그 다음에 3을 다시 씁니다. 그래서 코드는 정확히 프로그래밍 할 것입니다. Galister가 잠금 장치를 추가하는 방법을 설명했습니다.이 주석에 대한 한 쪽 메모 : 컴퓨터에서의 작업은 거의 절대 에서 발생합니다.)

+0

나는 병렬로 합을 잡으려고한다. –

+0

'컴퓨터에서의 작업이 정확히 같은 순간에 거의 일어나지 않습니다. '하나의 핵심 CPU가 있다면 좀 그렇습니다. 거의 아무도 요즘 않습니다. 또한 단일 코어 CPU에서도 연산이 원자 적으로 수행되지는 않습니다. 복합 연산 자체가 서로 얽혀 있기 때문에 다른 연산이 "앞"또는 "후"발생한다고 말할 수는 없습니다. – Servy

+0

@Dino : 어떻게 작동했는지 기억해 둡니까? 종이에 동시에 3 개의 숫자를 어떻게 추가 하시겠습니까? 코드에서 수행하는 작업은 세 사람에게 다른 번호에 숫자 (3)를 추가하는 것과 동일하지만 다른 사람들이 무엇을하고 있는지 알지 못합니다. 따라서 그들은 '다른 숫자'만 초기 숫자 (0)로 알고 있습니다. – JHBonarius