728x90
영화를 보다가 화장실에 가고 싶은데 다른 사람이 변기를 차지하고 안에서 잠금장치를 걸었다면 우리는 고민한다.
1. 사람이 나올 때까지 그 앞에서 계속 기다릴지
2. 잠시 자리로 돌아갔다가 나중에 다시 와서 다시 문을 두드릴지
3. 영화관 직원에게 부탁하여 화장실에 자리가 나면 나에게 알려달라고 할지
두 번째 상황이 바로 Context Switching이다. Context Switching이란 작업을 진행 중인 스레드가 자신의 작업이 완료되지 않은 상황에서 자신의 작업을 잠시 저장하고 다른 스레드에게 CPU 점유권을 양보하는 작업을 말한다.
C#으로 작성된 내용입니다.
using System;
namespace ServerStudy
{
class Lock
{
volatile int _locked = 0; // volatile 변수는 최적화에서 제외되고 항상 메모리에 접근함
public void Acquire()
{
while (true)
{
int expected = 0;
int desired = 1;
if (Interlocked.CompareExchange(ref _locked, desired, expected) == expected)
break;
//Thread.Sleep(1);
//Thread.Sleep(0);
Thread.Yield();
}
}
public void Release()
{
_locked = 0;
}
}
class Program
{
static int _num = 0;
static Lock _lock = new Lock();
static void Thread_1()
{
for (int i = 0; i < 100000; i++)
{
_lock.Acquire();
_num++;
_lock.Release();
}
}
static void Thread_2()
{
for (int i = 0; i < 100000; i++)
{
_lock.Acquire();
_num--;
_lock.Release();
}
}
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);
}
}
}
결과는 SpinLock과 다를 게 없지만 Thread.Sleep(1), Thread.Sleep(0), Thread.Yield()가 추가되었다. Thread.Sleep(N)은 N 밀리초 만큼 스레드를 멈추라는 뜻이다. 그러나 Sleep(0)은 다른 뜻을 가진다.
·Thread.Sleep(1)
다른 스레드에게 CPU 점유권을 양보하라는 뜻이다. 스레드 간 우선순위는 신경쓰지 않는다. (1밀리초만큼 스레드를 멈춤)
·Thread.Sleep(0)
자신과 다른 스레드 중 우선순위가 높은 스레드에게 CPU 점유권을 양보한다. 자신보다 우선순위가 높은 스레드가 없거나, 다른 스레드와 자신의 우선순위가 같다면 자신에게 점유권이 돌아간다.
·Thread.Yield()
지금 실행 가능한 다른 스레드가 있으면 그 스레드를 바로 실행한다. 실행 가능한 스레드가 없으면 자신이 대기한다.
728x90
'공부 > 게임 서버' 카테고리의 다른 글
[게임서버] AutoResetEvent와 ManualResetEvent (0) | 2022.05.31 |
---|---|
[게임서버] 데드락(DeadLock)이란? (0) | 2022.05.26 |
[게임서버] 스핀락(Spinlock)이란? (0) | 2022.05.25 |
[게임서버] 상호배제 - Monitor.Enter, Monitor.Exit (0) | 2022.05.24 |
[게임서버] Interlocked란? (0) | 2022.05.24 |