우리가 이때까지는 c#문법만을 사용을해가지고 막 만들었었는데
서버가 들어가게 되면은 서버는 멀티쓰레드를 활용을 해야하는데
멀티쓰레드를 알기 위해서는
컴퓨터 구조 원리랑
운영체제에 대한 기본적인 지식이 필요하다.
그래서 당장 코드부터 보기보다는 스토리를 하나 들려주고자 한다.
그래서 멀티 쓰레드는 식당을 운영하는 것과 괴장히 비슷하다고 했다.
그래서 이렇게 직원을 뽑았다.
그런데 이 직원은 로봇 직원이다라고 가정을 해보자
로봇의 특징은 알아서 움직이지 않고 뭔가를 공급을 주어야 움직이다라고 가정을 해보자.
그래서 영혼을 넣어주어야 움직인다.
그런데 지금 영혼은 하나인데 로봇은 4명이라 한명한테 밖에 영혼을 못주는데
모두 4명을 다 만족을 시킬 수는 없다.
그래서
이 영혼이 0.01초마다 왓다갓다거려서
영혼을 모르는 사람들은 다 잘 움직이네? 라고 생각하게 될것이다.
그래서 식당 운영이 다 잘되었다.
-끝-
인데
이것을 컴퓨터에 비유를 해보면은
이런식이 될것이다.
그리고 이제 이런식으로 프로그램을 켰다라고 가정을 했을때
그런데 프로그램을 키기만 하면 될 것이 아니라 뭔가가 이녀석들을 실행을 해주어야 하는데
아까말한 직원(쓰레드)를 한명씩을 배치를 했다.(일꾼 같은 개념이다)
우리가 그런데 일꾼을 만들어 준적은 없다 == 기본적으로 하나의 프로그램에 default값으로 쓰레드가 들어가 있다.(== 싱글 쓰레드)
MMO서버 같은 경우에는 일꾼을 여러마리를 두어서 관리를 할것이기 때문에
쓰레드가 두마리이다(사진상에서)
그래서 쓰레드를 만든 것까지는 굉장히 아름다운데
이녀석들이 실제로 실행이 되어야 의미가 있을 것이다.
그렇다면
실행 하는 주체 는 누구냐?
비로 CPU이다.
우리가 컴퓨터 부품 중에서 중요한것들이 여러가지가 있다
GPU, CPU, RAM, SSD ... 이런 부품들이 있는데
인간의 두뇌의 역할을 하는 것이 CPU라는 것이다.
이녀석이 덧셈 뺼샘, 온갖 계산, 그리고 어디다가 메모리를 저장을 할지 다 연산을 해주는 그런
뛰어난 녀석이다.
요즘에는 Core가 여러개가 있다(CPU종류)
한개의 CPU안에다가 멀티코어, 듀얼 코어, 쿼드 코어 이런 용어들을 쓰는데
일단은 이해를 쉽게하기 위해서 코어가 하나만 있다고 가정을 해보자.
그러니까 연산을 하는 두뇌가 하나밖에 없다라고 가정을 하면은
이녀석이 아까 처음에 본 영혼에 해당하는 녀석이다.
그러니까 영혼이 직원한테 빙의를 해야지만 움직이는 것처럼
우리 CPU코어도
실제 쓰레드를 실행을 해야지만
그 쓰레드가 실제로 동작을 하게 될 것이다.
그런데 아까 말한것 처럼 CPU코어가 실행할 수 있는 쓰레드는 하나 밖에 없다.
즉, 무조건 1 : 1 로 하나씩만 실행을 할 수 있는데
그런데 지금은 프로그램을 여러개를 켜놓은 상태이다.
그런데 코어는 하나밖에 없는데 프로그램은 여러개가 있다면 어떻게 해야할까??
아까와 마찬가지로 굉장히 빠른 시간안에 왔다 갔다 하면 되는 것이다.
그림판을 아주빠르게 실행했다가, 메모장을 실행했다가, 서버를 실행했다가 이런식임
우리 눈으로 보기에는 모든 프로그램들이 동시에 실행이 되는 것처럼 보이게 되는 의미이다.
그리고 이 설명이 실제로도 굉장히 정확한 예시 설명이다.
요즘 세대 윈도우는 당연한것인데
윈도우 이전의 도스는 하나만 실행이 되기때문에 게임을 실행을 하면 나머지 프로그램들은 다꺼지는 것이여서 당연한 것은 아니였다.
여기 파란선은 식당관리자(신의 영역)의 영역이라고 말을 했었는데
그것을 컴퓨터에 비유를 하면 운영체제게 작동을 하는 커널 모드라는 것이 있는데
운영체제를 말하는 것은 Linux, window이런것들을 말하는 것이다.
그리고 윈도우도 두가지 영역이 있는데
위에단계
즉, 일반적인 프로그램들을 실행하는 유져 영역이 있고
아래 단계
즉, 조금더 중요한 프로그램들을 실행하는 커널 모드라는 것이 있다.
커널모드에서는 진짜 windows의 핵심적인 그런 것들이 실행 되고 있다고 생각하면 된다.
어쨋든 거기서 관리를 해가지고 그다음에 어떤 프로그램을 실행시킬지 정해준다고 보면 된다.
이것이 스케쥴링 의 개념이 되는 것이다.
그런데 모든 프로그램이 다 공평하다고 볼 수 없다.
어떻게 보면 하찮은 그런 프로그램이다.
그래서 MMO서버가 더 중요한 프로그램이 될 수 있다.
그렇다는 것은 스케쥴링을 할 때 우선순위를 정할 수 있는데
굵게 표시된 것처럼 우선순위를 훨씬 높여서 한쪽을 몰빵 할 수도 있다.
그래서 모든 프로그램들을 똑같은 시간동안 실행해야된다는 그런 조건은 없다는 얘기가 된다.
그러면 이제 다른쪽이 실행이 잘 안되는 현상이 발생하는데
이것이 바로 기아현상 이라고 한다.
그리고 다음으로 알아볼 것은
이것의 역사적인 유래를 곰곰히 살펴보면은
2000년대 초반부터 매년 CPU의 성능이 두배씩 좋아졌는데
나중에는 발열이 심해져서 물리적인 한계로 인해가지고
코어를 더이상 빠르게 할 수 없게 되었다.
그래서 칩 제조사들이 생각을 한게
하나를 더이상 뛰어나게 만드는것이 불가능 하다면
코어수를 늘리면 어떨까라는 아이디어에 착안을 해가지고
CPU에다가 코어수를 늘리는 방향으로 발전을 해왔다
영혼의 예로 들면 영혼의 갯수가 4개 8개 이런식으로 많아 졌다는 것이다.
그런데
처럼 쓰레드를 무작정 이렇게 막 늘리면
여전히 문제가 되는 것이 무엇이냐 하면은
빙의를 한다는 작업 자체가 엄청 부담이 되고 부하가 많이 걸리는 작업이다.
그러니까 CPU코어가 하나의 쓰레드를 실행을 시키다가
다른 쓰레드로 옮겨타는 그 과정이
사실은 굉장히 무겁고 힘든 작업이기 때문에
무작정 쓰레드를 늘린다고 성능이 좋아지리라는 보장은 절대 없다.
처럼 코어수만큼 쓰레드를 실행 시키는 것이 가장 빠르고 이상적인 상황이다.
그리고 이제 쓰레드를 사용을 하는 것은 좋은데
이녀석들을 어떻게 사용을 하는지도 굉장히 궁금하다.
예를들면은 아까 쓰레드는 직원이라고 했으니까
이런식으로 하나하나씩 자기의 담당 부서를 정해가지고
뭐 한명은 계산대를 맡고 누구는 서빙을 맡고 이런식의 구성은
구성을 하기 나름이다.
그리고 쓰레드를 만들면 어떤일이 일어날지 또 궁금하다.
그래서 이것을 또 살펴보면은
모든 쓰레드들은 일단인 Heap영역과 Data영역은 모두다 공유해서 사용하게 된다.
반면, 스택 영역은 다 구분되어서 자신만의 스택 영역을 받는다.
이렇다는 것은
멀티쓰레드 환경, 즉, 직원이 여러명 있는 환경에서
스택을 접근하는 것은 아무런 문제가 없는데
동시에 공용으로 사용할 수 있는 영역에 접근을 하는 것은
이제 슬슬 문제가 된다는 얘기가 된다.
이게 왜? 문제가 되냐하면은
(사진)
우리는 분명 직원들을 분배를 하려고 여러명을 둔건데
애내들이 서로 얽히고 섥히고 하다보니까
한쪽으로만 다 몰리는 상황이 발생 할 수도 있다.
사진과 마친가지고
쓰레드 관리도 분명 이점은 있지만
관리를 잘못하게되면
직원을 한명 두는것만 못하게되는 상황이 발생하게 될 것이다.
예를들어 어떤 식당에서 직원을 한명만 두어서 관리를 했을 때 잘 굴러가던 것이
100배큰 식당을 운영을해서 직원을 100명 둔다고 가정을 하면은
이것이 과연 관리가 쉬울지 생각을 해보면은 된다.
당연히 어려울 것이다.
이미 주문을 받은 테이블에 또 주문을 받는 다던가
한쪽 테이블을 까먹고 아무도 안챙기는 상황도 발 생할 수도 있고
일을 아름답게 잘 분배하는 것은 어렵지만
결국, 우리가 이것을 어떻게든
잘 굴리게되는 그런 목표를 잡고 이 목표를 다루게 될 것이다.
그래서 곧 멀티쓰레드 환경이라는 것은
직원을 많이 둔다음에
그 직원들이 최대한 효율적으로 움직이게끔
만들어야 한다는 것이다.
그래서 식당이 아름답게 잘 돌아가면 우리 MMO서버도 아름답게 잘 굴러간다는 것이다.
이렇게해서 멀티쓰레드 개요를 알아보았다.