Unity

[인프런 강의 정리] 데드락, 락 구현 연습

wny0320 2024. 9. 25. 19:06

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

 

[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


데드락

DeadLock 교착상태

일반적인 상황에서 데드락이 발생하는 상황

  • 리소스를 하나씩 들고 있는 상태에서 다른 리소스를 기다리고 있는 경우

해결방안

  • 둘 중 하나의 리소스가 아닌 1번 리소스를 가진 쓰레드가 대기, 다른 리소스를 점유한 쓰레드는 점유 해제

데드락 예시

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

namespace ServerCore
{
    class SessionManager
    {
        static object _lock = new object();

        public static void TestSession()
        {
            lock(_lock)
            {

            }
        }

        public static void Test()
        {
            lock(_lock)
            {
                UserManager.TestUser();
            }
        }
    }
    class UserManager
    {
        static object _lock = new object();

        public static void Test()
        {
            lock (_lock)
            {
                SessionManager.TestSession();
            }
        }

        public static void TestUser()
        {
            lock (_lock)
            {

            }
        }
    }
    class Program
    {
        static int number = 0;
        
        
        static void Thread_1()
        {
            for (int i = 0; i < 100000; i++)
            {
                SessionManager.Test();
            }
        }
        static void Thread_2()
        {
            for (int i = 0; i < 100000; i++)
            {
                UserManager.Test();
            }
        }
        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);
        }
    }
}

추가 내용들

더보기
// Monitor.TryEnter() 시간동안 리소스를 얻지 못하면 실패
// 하지만 잘 사용하지 않음
// 일반적인 경우는 데드락은 일어나면 고치는 쪽으로 함
// 동시에 쓰레드가 작업하는 경우가 QA보다 Live에서 많아서 그때 많이 발생함
// 100ms만 차이나도 데드락이 발생하지 않는걸 볼 수 있음
// lock에 관련한 클래스를 하나 만들어, 우선 순위에 따라 crash를 내던지 할 수 있음

락 구현 연습

락이 걸려 있을때 다른 쓰레드의 구현

  1. 기다리기(스핀락의 개념, 구현되면 무한 대기이기 떄문에cpu점유율이 튐)
  2. 일단 자리로, 나중에 다시(리소스 소유권을 포기하고 다시, Context Change 문맥 교환에 대한 내용, 문맥 교환시 자원이 많이 들어감, 다른 쓰레드가 먼저 점유할 가능성 있음, 다른 작업을 하다 돌아옴)
  3. 커널한테 리소스가 남으면 알림을 받음(Envent 방식을 사용해서 신호를 받음)