(C# : Server) 6. Interlocked

Posted by : at

Category : Charp-Server


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를 다른 스레드에서 언제접근중일지 모름
}

매번 이런 방식으로 해결해야하나?
그래서 다른 방법이 존재… 다음강좌에서 참조


About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links