static volatile int number = 0
static void Thread_1()
{
for(int i = 0; i < 100000; i++)
number++;
}
static void Thread_2()
{
for(int i = 0; i < 100000; i++)
number--;
}
static void Main(string[] args)
{
Task t1 = new Task(Thread_1);
Task t2 = new Task(Thread_2);
t1.Start();
t2.Start();
Task.WaitAll(t1, t2);
// 여기서 0이 나오지 않게 된다.
Console.WriteLine(number);
}
이게 말이 되나?
number++
동작을 할때 ecx레지스터에 복사 후 1을 증가하고 다시 복사하는 과정을 거친다.
마치 아래와 같이 동작한다
int temp = number;
temp += 1;
number = temp;
이러한 동작속에서 우리가 생각했던 값과 다른 값이 나타나게 된다.
이런 문제를 아토믹하지 못해서 생기는 문제라 말하며…
해결해보자.
static void Thread_1()
{
for(int i = 0; i < 100000; i++)
// 이렇게 해서 아토믹한 연산을 가능하게 만든다.
Interlocked.Increament(ref number);
// 단, 이 동작은 성능이 나쁘다
}
static void Thread_2()
{
for(int i = 0; i < 100000; i++)
Interlocked.Decrement(ref number);
}
static void Thread_1()
{
for(int i = 0; i < 100000; i++)
int ret = Interlocked.Increament(ref number);
// 참고로 Interlocked.Increament은 리턴을 받는데
// 리턴을 받는이유는 number가 현재 어떤값인지 알려주기 위함이다.
// ??? 그냥 number를 브레이크포인트에서 찍어보면 안되나?? -> 아주 싱글스레드 적인마인드
// number를 다른 스레드에서 언제접근중일지 모름
}
매번 이런 방식으로 해결해야하나?
그래서 다른 방법이 존재… 다음강좌에서 참조