Unity

[인프런 강의 정리] Interlocked

wny0320 2024. 9. 25. 19:01

이 글은 아래 강의를 정리한 글이다

 

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 강의 | Rookiss - 인프런

Rookiss | 네트워크/멀티쓰레드/운영체제 등 핵심 전공 지식을 공부하고 게임 서버를 바닥부터 만들어보면서 MMORPG 기술을 학습하는 강의입니다., MMORPG 개발에 필요한 모든 기술, C# + Unity로 Step By St

www.inflearn.com

해당 정리글을 한번에 보고 싶다면 아래 링크를 참조하길 바란다

 

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 | Notion

서버OT

mesquite-prune-8c9.notion.site


Interlocked가 필요한 이유에 대한 예시

더보기
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        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이 아닌 값들이 등장함. 이유에 대해서 알아보는 것이 이번 강의 주제
  • 경합조건(Race Condition)
    • 클라이언트의 요구와는 다르게 여러 쓰레드가 요청에 대해 처리한 상황
    • 위의 경우에서는 number에 값을 다시 넣어주는 과정에서 경합 조건이 발생
    • +) 원자성, 한번에 작업이 이루어져야함
    • ex) 아이템 교환 과정에서 usr1에서 usr2로 이동하는데 usr2의 인벤에는 아이템이 생성되었지만 usr1의 인벤에 아이템이 삭제되지 않은 경우 아이템 복사가 일어나게 됨

Interlocked 설명과 실습

더보기
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        static int number = 0;
        static void Thread_1()
        {
            for (int i = 0; i < 100000; i++)
            {
                Interlocked.Increment(ref number);
                // 원자적으로 연산을 함
                // 실행을 하게 되면 실행이 끝나기 전까지 다른 것을 안함
                // 혹은 아무것도 실행하지 않음
                // 단점은 성능에서 차이가 있음
                // 대신 경합조건을 해결할 수 있음
                // Interlocked는 결과 return 값이 존재함
            }
        }
        static void Thread_2()
        {
            for (int i = 0; i < 100000; i++)
            {
                Interlocked.Decrement(ref 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);
        }
    }
}