lock을 다른 쓰레드가 점유한 상황에서 쓸 수 있는 lock획득 행동 중 하나는 다시 제자리로 돌아왔다가 이후에 lock획득을 다시 시도하는 것이다.(랜덤메타)
위 그림처럼 커널모드에서 time slice쿠폰을 발행하고 쓰레드가 time slice를 모두 소진하면 커널에 반납한다. 커널에서는 스케쥴에 따라 쓰레드에 time slice쿠폰을 주고 해당 쓰레드는 time slice소진까지 작업을 하는 행동을 반복한다.
왼쪽 그림은 system call을 하면 커널모드로 컨텍스트 스위칭이 일어남을 보여준다.
오른쪽 그림은 쓰레드가 준비상태에 있다가 time slice를 할당받아 실행하고, 비자발적, 자발적 컨텍스트 스위칭이 일어남을 설명한다.
이전에 만든 spin lock을 lock을 못 얻었다면 커널에 time slice를 반납하게 만들어보자.
class SpinLock
{
public:
void lock()
{
// CAS (Compare - And - Swap)
bool expected = false;
bool desired = true;
while (_locked.compare_exchange_strong(expected, desired) == false)
{
expected = false;
//this_thread::sleep_for(std::chrono::milliseconds(100));
this_thread::sleep_for(0ms);
//this_thread::yield(); // == this_thread::sleep_for(0ms)
}
}
void unlock()
{
_locked.store(false);
}
private:
atomic<bool> _locked = false;
};
참고로 yield는 양보한다는 의미이고 여기서는 time slice를 커널모드에 반납하는 동작을 수행한다.
this_thread::yield는 sleep_for(0ms)과 같다.
이전과 바뀐것은 sleep을 추가한 것 뿐이지만 실제 동작은 현재 쓰레드가 받은 time slice를 커널에 반납하는 것임을 알아두자.
참조 : [C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 - 인프런 | 강의 (inflearn.com)
Condition variable (0) | 2021.08.07 |
---|---|
Event (0) | 2021.08.07 |
SpinLock (0) | 2021.08.05 |
Lock 구현 이론 (0) | 2021.08.03 |
Dead Lock (0) | 2021.08.03 |
댓글 영역