본문 바로가기
프로그래밍/Game Dev

[C#] Interlocked

by YuminK 2023. 8. 26.

원자성이란?

어떠한 동작이 한번에 일어나야 하는 것을 의미한다.

 

예시) 돈을 송금하는 상황

1. 돈을 내 계좌에서 줄인다.

2. 상대 계좌에 돈을 늘린다. 

 

만약 1번까지만 성공하고, 2번에서 문제가 생겼다면?

원자성을 보장하지 않는 것이다. 

 

이를 막기 위해 Interlocked 함수를 이용한다. 

 

다음 코드는 쓰레드를 실행시켜 공유 변수인 number에 접근하는 예제이다. 

0이 나오지 않는다. 

 

class ThreadProgram
{
    static 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);

        Console.WriteLine("number = " + number)
    }
}

 

number를 더하거나 뺴는 연산은 데이터의 위치를 참조하고 값을 증가 시키는 연산을 포함한다.

이러한 연산을 여러 쓰레드에서 동시에 처리하여 0이 아닌 다른 값이 나오게 된다. 

 

위 함수를 Interlocked를 사용하는 형태로 바꾸면 결과가 0으로 보장된다.

Interlocked는 ALL or Nothing 방식으로 동작하는데,

먼저 선점한 쓰레드의 동작을 끝낸 이후에 다음 쓰레드가 접근할 수 있도록 지원한다. 

 

static void Thread_1()
{
    for (int i = 0; i < 100000; ++i)
        Interlocked.Increment(ref number);
}

static void Thread_2()
{
    for (int i = 0; i < 100000; ++i)
        Interlocked.Decrement(ref number);
}

'프로그래밍 > Game Dev' 카테고리의 다른 글

[C#] AutoResetEvent  (0) 2023.08.26
[C#] SpinLock  (0) 2023.08.26
[C#] MessagePack  (0) 2023.08.26
[C#] 메모리 베리어  (0) 2023.08.26
[C#] 캐시 메모리 철학  (0) 2023.08.26

댓글