InterLocked

littleDev·2024년 5월 29일

Server

목록 보기
2/2
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        private 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);
        }
    }    
}

이 코드를 보고 어떤 결과가 출력될지 생각해보자
당연히 0이라는 값이 출력될거라고 예상된다.

하지만 결과는 생각과 다르다. 왜 이럴까?
바로 원자성을 고려하지 않아서 그렇다
우리가 작성한 코드는 이렇지만, 사실은 아래와 같이 실행된다.

생각보다 이런 현상은 보편적이다.

게임을 예로 들어보자. 게임 내의 골드를 100 소비하고, 대신 검을 얻는 시스템이 있는데 서버가 다운되어 골드는 100을 소비했는데, 검을 얻지 못하는 경우가 있다.

위 현상을 방지하려면 아래와 같이 Interlocked 사용하면 된다.

단점 : Interlocked이 끝날때까지 다른 코드는 실행되지 않기에 성능이 떨어짐

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);
	}
}
profile
매일 성장하고싶은 개발자

0개의 댓글