이 글은 아래 강의를 정리한 글이다
[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
// 쓰레드를 쉬다 오게 하는 방법 3가지
Thread.Sleep(1);
// 무조건 1ms 휴식
// 실제시간은 운영체제의 스케쥴러가 관리
Thread.Sleep(0);
// 조건부 양보
// 나보다 우선순위가 낮은 애들한테는 양보 불가
// 나보다 높은 우선 순위가 없으면 다시 본인이 작업
Thread.Yield();
// 관대한 양보
// 지금 실행이 가능한 쓰레드가 있으면 실행
// 실행 가능한 쓰레드가 없다면 남은 시간 소진
위 코드에서 쓰레드가 다른 쓰레드에게 양보하는 것을 배웠는데, 이 때 소모되는 비용에 대해 알아보자
Context Switching
- 유저 영역의 프로그램 쓰레드끼리 스위칭을 하기 위해서는 커널 영역의 cpu코어를 거쳐야함
- 레지스터는 다양한 레지스터가 존재함, RAM에서 그 프로그램에 필요한 데이터들을 뽑아서 일부는 레지스터에 복원하게 됨
- 양보를 하게 되면 이런식으로 비용이 발생하게 됨
- 따라서 어느게 효율적인지는 생각을 해봐야한다
Auto Reset Event
- 자동으로 잠김
Manual Reset Event
- 수동으로 잠김
class Lock
{
AutoResetEvent _available = new AutoResetEvent(true);
// 커널 레벨에서의 bool과 같음
// 매개변수는 bool, 생성시 lock을 한 상태인지 아닌지 정함
// spinlock보다 확연히 오래 걸리는걸 확인할 수 있음
public void Acquire()
{
_available.WaitOne();
// _available.Reset(); // => bool = false 넣는 과정과도 같음
// 이 과정이 WaitOne에 포함
// 입장 시도
// 성공시 자동 잠금
}
public void Release()
{
_available.Set();
// flag = true
}
}
class Lock
{
ManualResetEvent _available = new ManualResetEvent(true);
// 이 기능은 한 번에 하나만 받을 필요가 없을 때 사용
public void Acquire()
{
_available.WaitOne();
_available.Reset(); // 문을 닫는 개념
// 결국 이 문제들은 문이 잠겨있는지 확인하고 들어가서 닫는게 하나로 되어있지 않아서 문제
}
public void Release()
{
_available.Set(); // 문을 열어주는 개념
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ServerCore
{
class Program
{
static int _num = 0;
static Mutex _lock = new Mutex();
// spinlock에 비해 느림
// 느린 이유는 아까와 같이 커널 영역에서 돕기 때문
// event들과 차이점
// 몇 번 잠궜는지 정보가 있어서 그 만큼 해제를 해야지 잠금이 해제됨
// ThreadId 를 가지고 있어서 잠금을 한 쓰레드를 기억하고 있다가 다른 쓰레드가 접근할 때 잡아주기도 함
static void Thread_1()
{
for (int i = 0; i < 100000; i++)
{
_lock.WaitOne();
_num++;
_lock.ReleaseMutex();
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; i++)
{
_lock.WaitOne();
_num--;
_lock.ReleaseMutex();
}
}
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(_num);
}
}
}
'Unity' 카테고리의 다른 글
[던전 크롤링 게임] 1.0 빌드본(2024.10.22 5차 수정) (0) | 2024.10.18 |
---|---|
[던전 크롤링] 인벤토리 시스템 리팩토링 (0) | 2024.09.29 |
[인프런 강의 정리] SpinLock (0) | 2024.09.27 |
[던전 크롤링] 인벤토리 시스템 (0) | 2024.09.25 |
[인프런 강의 정리] 데드락, 락 구현 연습 (0) | 2024.09.25 |