KoreanFoodie's Study
[C++ 게임 서버] 1-8. Sleep 개념과 구현 본문
[C++ 게임 서버] 1-8. Sleep 개념과 구현
핵심 :
1. Lock 을 잡을 수 없을 때, 일정 시간 동안 기다리게 할 때 sleep 을 사용한다.
2. Sleep 을 사용하면 일정 시간 동안 해당 쓰레드는 준비 상태에 있다가 다시 돌아온다. 이 시간동안에는 CPU 자원을 사용하지 않는다. 대신 Kernel Space 로 전환되는 과정에서의 비용은 발생한다(컨텍스트 스위칭).
3. yield 는 쓰레드에게 주어진 Time Slice 를 즉시 반납하도록 하며, 스케줄러에게 쓰레드가 어떤 일을 할지 알아서 정해달라고 요청을 하게 된다.
이전에 Lock 구현 이론에서 설명한 것 중 두번째인, '랜덤 시간 후 복귀' 메타가 바로 sleep 이다.
이전 글에서 SpinLock 을 이용해 '무작정 기다리는' 전법을 구현했었는데, 이번엔 일정 시간을 기다리는 Sleep 을 구현할 것이다.
사실 이전 SpinLock 에서 아래와 같이 sleep 을 시키는 코드를 넣어주면 끝이다 🤣
class SpinLock
{
private:
atomic<bool> _locked = false;
public:
void lock()
{
bool expected = false;
bool desired = true;
while (_locked.compare_exchange_strong(expected, desired) == false)
{
expected = false;
// 100ms 동안 대기 상태
this_thread::sleep_for(std::chrono::milliseconds(100));
// 아래는 사실 0ms 동안 자는 것과 동일하다. 할당된 Time Slice 를 반납한다는 것을 의미
this_thread::yield();
}
}
void unlock()
{
_locked.store(false);
}
};
쓰레드가 대기 상태로 들어가게 되면, CPU 사용을 더 이상 하지 않고 일정 시간동안 준비 상태로 들어간다.
이 과정에서 Kernel space 에 들어가게 되는데... 검색해보니 OS/CPU 마다 정책이 달라 꼭 Kernel Space 로 들어가지 않을 수도 있다고 한다 😅
아참, 좀더 자세히 설명하자면... 아래 그림을 참고하자.
일반적으로 쓰레드는 얼마나 CPU 자원을 쓸 수 있는지 쿠폰(?) 같은 것을 받게 되는데, 이것을 OS 에서는 'Time Slice' 라고 한다. 주어진 Time Slice 를 다 쓰게 되면, 자원을 반납하고 준비 상태로 되돌아가는데...
Sleep 을 사용하면, 자동으로 돌아가도록 하는게 아니라 수동으로 자원을 반납하게 하게 만들 수 있다 😁
참고로, yield 를 사용하면 Time Slice 를 즉시 반납하고 커널 영역으로 쓰레드를 넘겨줘, 스케줄러가 알아서 사용하도록 해 준다 😉
좀더 자세한 설명은 이 블로그를 참고하자!
'Game Dev > Game Server' 카테고리의 다른 글
[C++ 게임 서버] 1-10. Condition Variable (조건 변수) (0) | 2023.07.14 |
---|---|
[C++ 게임 서버] 1-9. 이벤트 구현 (+ Handle) (0) | 2023.07.14 |
[C++ 게임 서버] 1-7. SpinLock 개념과 구현 (0) | 2023.07.11 |
[C++ 게임 서버] 1-6. Lock 구현 이론 (0) | 2023.07.11 |
[C++ 게임 서버] 1-5. DeadLock 의 개념과 기초 (+ std::lock) (0) | 2023.07.10 |
Comments