락의 경우 서버 개발을 할 때 너무 필수적이고, 면접에서 자주 나오는 경우다. 그렇기 때문에 다양한 방식으로 Lock을 구현하는 연습은 꽤나 중요하다. 즉 우리는 이 화장실의 좌물쇠를 만드는 연습을 충실히 해보자.
내가 직장에서 일하고 있다가 직장 화장실을 갔을 때 누군가 들어갔다. 화장실 앞에서 대기하는 방법은 3가지로 요약할 수 있다.
- 무작정 기다린다. - 화장실 내에서 손 씻는 소리가 난단건 곧 나온다는 것이다. 그리고 자기 일터와 화장실을 왔다갔다 하는 시간은 굉장히 오래 걸리니까 그냥 계속 기다리는 방식이다. 이 방식을 컴퓨터로 하면 스핀락이라고 한다. (계속 루프를 돌면서 lock이 풀렸나 확인하는 것이다.
- 일단 일터로, 화장실은 다시 돌아온다. - 먼저 일자리로 돌아가서 일을 하다가 3분 정도 뒤에 돌아오면 화장실이 비어있을 확률이 높을 것이다. 하지만 확실성이 없는 즉 운에 맡기는 식이다. 예로 들어 10초 뒤에 나올 수 있는데 돌아가고, 그 3분이 되기 전에 다른 사람이 들어가면 결국 또 기다려야 된다.
- 부하 직원한테 기다리라고 시킨다 (갑질이다. 실제로는 절대 일어나면 안 된다!!!!) - 화장실이 비면 이 직원이 나한테 통보하게 하는 것이다. 문제는 이 방식은 또 다른 리소스를 만드는 것이라 무거운 과정이라 볼 수 있다.
1번은 Sprinlock이라 부르며, 3번은 이벤트라고 부른다. 그리고 일자리와 화장실을 왔다갔다 하는 과정을 컨텍스트 스위칭이라 한다.
컨텍스트 스위칭?
결론부터 말하면, CPU 관점에서 보면
다시 예전에 이야기 한 레스토랑 타이쿤의 예시로 돌아가보자. 한식, 일식, 패밀리 레스토랑 내에 직원이 각각 1명,1명,2명이 있고 우리의 손은 이 4명의 몸을 왔다갔다 한다고 가정하자. 그리고 이 과정에는 이런 손을 왔다갔다 하게 하는 내 몸이 있다. (즉 뇌가 있다.)
OS의 경우도 결국 프로그램이라 우리의 손은 그 OS에 있는 직원도 컨트롤을 해줘야 한다. (실제로는 이 부분은 마이크로소프트가 만든다)
만약 내 손이 하나의 직원을 선택할 때 내 손가락이 직원을 클릭하기 위해서 가야 하며, 반대로 다른 직원을 클릭하기 위해서는 내 손가락이 또 떼졌다가 그 직원 아이콘까지 손가락을 대서 클릭하는 식이다. 이 손가락이 왔다갔다 하는 시간이 바로 컨텍스트 스위칭 시간이다.
이 것을 실제 컴퓨터로 가면, 현재 스레드가 실행중인 프로그램에 대한 상태는 레지스터에 들어갔다가, 다른 프로그램으로 이동하기 전에 이 상태값을 램에 저장을 하고, 다시 다른 프로그램에 대한 정보를 레지스터에 등록한다. 즉 이 과정은 유저 모드에서 커널 모드로, 커널 모드에서 유저 모드로 가는 과정이고, 이 과정은 굉장히 정말 시간을 많이 먹는 것이다. 하지만 이 컨텍스트 스위칭은 피할 수 없는 필연이다. (즉 줄여야 하는 것은 맞지만 이 과정은 죄악은 아니다)
다시 락으로 돌아가면, 이 메서드가 빨리 실행된다 가정된다면 스핀락을 이용해서 구현하고, 그 외 만약 오래 걸린다고 하면, 2,3번 방법을 이용하는 식으로 즉 하나만 쓰는 것이 아니라 그때그때 섞어서 쓰는 편이 좋다.
'Game Server' 카테고리의 다른 글
[C++/서버] Sleep (0) | 2022.07.12 |
---|---|
[C++/서버] Spinlock (0) | 2022.07.07 |
[C++/서버] DeadLock (0) | 2022.07.07 |
[C++/서버] Lock (0) | 2022.07.07 |
[C++/서버] Atomic (0) | 2022.07.04 |