Server

[Concurrency] 스레드 개요

dev-ohdam 2024. 7. 11. 19:58

 

 

이 글을 읽기에 앞서 프로세스와 스레드의 개념이 헷갈린다면, 운영체제와 관련된 개념을 먼저 익히고 오는 것을 추천한다

 

스레드 개념에 관해, 필자는 다음과 같이 간단하게 정의한다.

 

프로세스 내에서 처리되는 독립적인 실행 단위.

 

좀 더 자세하게 말하자면, 스레드는 프로세스 내에 자원을 공유하며 이를 이용해 특정 작업을 수행하는 "일손"이다.

 

 

 다음 프로세스들을 살펴보자. (게임, 웹브라우저)

게임만 하더라도, 로그인, 아이템 구매 및 결제, 전투 등 하나의 프로세스에 여러 가지 기능을 제공한다.

또 웹 브라우저만 하더라도 파일 다운로드, 미디어 시청 등 여러 가지 기능을 제공한다.

 

이런 처리방식에 가능하게 된 것에 관해선, 기기의 발전이 큰 기여를 했다.

현대의 프로세서들은 단일 작업만 처리하는 것이 아니라, 여러 작업을 동시에 처리할 수 있는 멀티코어 구조를 가진다.

그렇기 때문에, 이런 멀티스레드 방식으로 동작하는 다양한 프로세스들을 처리할 수 있다.

 

 여기서 만약, 우리가 파일을 다운로드 하는 동안, 브라우저와의 상호작용이 불가능하다면 어떨까?

굉장히 불편할 것이다.

 

 여기서 우리가 주목해야할 사실은, 어떤 하나의 작업을 수행하는 동안에, 다른 작업을 병렬적으로 처리할 수 있음에 주목해야한다. 우리는 유튜브로 영상을 시청하는 동시에 멈춤 없이 파일을 다운받을 수 있고, 게임을 하면서  몬스터와 전투를 하는 동시에 파티원과 채팅도 수행할 수 있다. 

 

 이런 행위들을 가능하도록 하는 것이 바로 멀티 스레드를 활용한 병렬 처리이다.

 특히 게임 서버 프로그래밍의 경우, 대규모의 인원들에게 원활한 멀티 플레이 환경을 제공하기 위해선 멀티 스레드를 활용한 프로그래밍에 관한 이해와 활용이 필수적이다.

 

그렇다면 우리는 스레드를 어떻게 활용해야 하는가?

 

예를 들어 하나의 게임 프로그램이 있다고 가정하자.

 

우리는 유저의 정보를 저장하기 위해 DB와 상호작용하는 작업도 필요하고,

유저끼리 채팅을 하기 위한 작업도 필요하고,

기본적으로 게임 내 상호작용을 업데이트 하기 위한 작업도 필요하고,

게임의 시각적인 정보를 렌더링 하기 위한 작업도 필요하다.

 

 앞서 언급했 듯, 우리는 어떤 작업을 수행하는 과정에서 다른 작업을 할 수 없다면 유저 입장에선 굉장히 답답할 것이다.

(Ex. 다른 사람으로 부터 채팅 메시지를 받는 동안, 게임 화면이 안그려진다던가... 등)

그렇기 때문에 우리는 이 다양한 작업에 관해 스레드를 여러 개 활용하여 병렬적으로 처리하는 것이다.

 

여기서 우리는 이 작업들을 처리하기 위해 몇 개의 스레드를 사용할 것인가?(스레드 할당의 유연성),

각 스레드 별로 어떻게 일을 분배할 것(작업의 병렬 처리 계획)인가? 를 잘 생각해야한다.

 

 이 내용은 당연하게도 개발자 별로 생각하는 것이 모두 다를 것이다.

어떤 게임은 고퀄리티 그래픽을 처리해야하기 때문에 렌더링 작업 하나에 여러 개의 스레드를 할당할 수 도 있고,

어떤 게임은 DB 처리 스레드, 채팅 스레드, 게임 업데이트 스레드, 렌더링 스레드 등 각 작업 별로 하나 씩만 스레드를 할당할 수도 있다.

 

그 외에도 하나의 작업을 여러 스레드로 처리한다고 했을 때, 각 스레드 별로 공유되는 자원에 관해 어떻게 동기화를 수행할 것(스레드 간의 동기화)인지? 스레드를 어떻게 효율적으로 관리할 것인지?  생각할 것이 매우 많다.

 

필자는 앞으로 스레드의 생성부터 활용 예시까지, 내가 지금까지 작성해왔던 코드를 기반으로 한번 설명해보고자 한다.