수업

  • 이미지 1: 식당과 프로그램의 유사성.

    • 각 레스토랑은 프로그램.
    • 각 직원(로봇)은 쓰레드.
    • 영혼은 CPU 코어.
  • 이미지 2: 한식, 일식, 패밀리 레스토랑의 비교.

    • 쓰레드가 많아질수록 코어와의 적절한 매칭이 중요.
  • 이미지 3: 게임 로직, 클라이언트 세션, DB 쓰레드.

    • 쓰레드마다 명확한 역할 분배의 중요성.
  • 이미지 4: 그림판, 메모장, MMO 서버.

    • 스케줄링 우선순위와 멀티쓰레드의 작업 분배.
  • 이미지 5: 힙과 스택 메모리 구조.

    • 스택은 쓰레드마다 보유.
    • 힙은 모든 쓰레드가 공유.
  • 이미지 6: "이론 vs 현실"의 차이.

    • 이상적으로 쓰레드가 분배되지 않는 현실을 보여줌.

1. 멀티쓰레드란?

멀티쓰레드(Multi-threading)란 하나의 프로그램(프로세스) 내에서 여러 개의 작업(쓰레드)을 동시에 실행하는 기술입니다.

하지만 CPU 코어의 개수보다 많은 쓰레드가 동시에 실행될 수 없으며, 운영체제의 스케줄러(Scheduler) 가 쓰레드 간 실행 시간을 분배하여 빠르게 전환하기 때문에 동시에 실행되는 것처럼 보이는 것입니다.

📌 비유: 멀티쓰레드 = 식당 운영

  • 프로그램 → "식당"
  • 쓰레드 → "직원"
  • CPU 코어 → "직원의 영혼(일할 수 있는 능력)"

즉, CPU 코어가 없으면 직원(쓰레드)은 일을 하지 못하며, 한 명의 직원(쓰레드)은 동시에 여러 테이블을 서빙할 수 없습니다.


2. 단일 쓰레드 vs 멀티쓰레드

💡 "단일 쓰레드"

  • 직원이 한 명뿐이라 모든 손님을 차례로 응대해야 함 → 처리가 느림
  • 식당(프로그램)이 바빠지면 손님(작업)이 쌓임 → 대기 시간이 길어짐

💡 "멀티쓰레드"

  • 여러 직원(쓰레드)이 동시에 일함 → 작업이 빠르게 진행됨
  • 손님이 많아도 여러 직원이 나눠서 처리 → 대기 시간이 줄어듦

🚀 게임 서버에서 적용

  • 단일 쓰레드 서버 → 하나의 요청이 끝나야 다음 요청을 처리
  • 멀티쓰레드 서버 → 여러 요청을 동시에 처리 가능

3. CPU 코어와 쓰레드의 관계

(1) 단일 코어, 다중 쓰레드

  • 단일 CPU 코어에서 여러 쓰레드가 빠르게 교체되면서 실행됨.
  • 실제로는 한 번에 하나의 쓰레드만 실행 가능하지만, 스케줄링을 통해 마치 동시에 실행되는 것처럼 보임.

(2) 멀티 코어, 멀티 쓰레드

  • 여러 코어가 있으면 실제로 여러 개의 쓰레드가 동시에 실행될 수 있음.
  • 코어 개수만큼 쓰레드를 병렬 실행할 수 있으며, 나머지 쓰레드는 기존처럼 빠르게 교체됨.

📌 CPU 코어가 많으면?
✅ 더 많은 작업을 동시에 실행 가능!
✅ 하지만 쓰레드가 너무 많으면 자원을 두고 경쟁하여 성능이 저하될 수 있음.

➡ 따라서, 적절한 쓰레드 개수를 유지하는 것이 중요!


4. 게임 서버에서의 쓰레드 관리

게임 서버는 여러 작업을 동시에 처리해야 하므로 멀티쓰레드 환경이 필수입니다.

💡 예제: 게임 서버의 쓰레드 역할 분담

역할쓰레드 종류
클라이언트 연결 처리네트워크 쓰레드
게임 로직 처리게임 로직 쓰레드
데이터베이스 연동DB 쓰레드
AI 및 NPC 행동AI 쓰레드

🎯 목표: 쓰레드를 적절하게 분배하여 서버의 성능을 극대화하는 것!


5. 멀티쓰레드의 메모리 구조

멀티쓰레드를 사용할 때 각 쓰레드는 메모리를 어떻게 공유할까?

(1) 스택(Stack)

  • 각 쓰레드마다 독립적인 메모리 공간을 가짐.
  • 지역 변수 및 함수 호출 정보를 저장.
  • 다른 쓰레드와 공유되지 않으므로 데이터 충돌이 발생하지 않음.

(2) 힙(Heap)

  • 모든 쓰레드가 공유하는 메모리 영역.
  • 동적으로 할당된 객체들이 저장됨.
  • 여러 쓰레드가 동시에 접근하면 Race Condition(경쟁 상태) 발생 가능!

📌 Race Condition (경쟁 상태)

  • 여러 쓰레드가 동시에 같은 데이터를 변경하려고 할 때 예상치 못한 결과가 발생하는 현상.
  • 예: 두 명의 직원이 동시에 같은 테이블의 계산서를 수정하려 하면 충돌 발생.

➡ 해결 방법

  • Mutex (뮤텍스, 상호 배제): 한 번에 하나의 쓰레드만 데이터에 접근하도록 제한.
  • Atomic 변수: 특정 연산을 원자적으로 수행하여 중간 상태를 방지.

6. 멀티쓰레드에서 발생하는 문제점과 해결 방법

(1) Deadlock (교착 상태)

  • 두 개 이상의 쓰레드가 서로가 필요한 리소스를 점유한 채 기다리면서 멈추는 현상.
  • 예: A 직원이 계산서 정리를 기다리고 있고, B 직원은 테이블 정리를 기다리지만 서로 교차된 작업을 점유한 상태라 진행 불가.

📌 해결 방법
Lock 순서 정하기: 항상 같은 순서로 락을 획득하도록 설계.
타임아웃 설정: 일정 시간 대기 후 락을 해제하도록 구현.


(2) Context Switching (문맥 전환 비용)

  • 운영체제가 쓰레드를 교체할 때, 현재 쓰레드의 상태를 저장하고 새로운 쓰레드를 로드하는 과정에서 발생하는 비용.
  • 쓰레드가 많을수록 문맥 전환이 잦아지고 성능이 저하될 수 있음.

📌 해결 방법
쓰레드 개수를 CPU 코어 수에 맞게 적절히 조절.
필요할 때만 쓰레드를 생성하고, 사용이 끝나면 정리.


7. 멀티쓰레드의 실무 적용

멀티쓰레드를 사용할 때 고려해야 할 몇 가지 중요한 개념들이 있습니다.

(1) 동기화(Synchronization)

여러 쓰레드가 같은 데이터를 수정할 때 데이터 손상을 방지하기 위해 동기화가 필요합니다.

Mutex (뮤텍스): 한 번에 하나의 쓰레드만 리소스 접근 가능
SpinLock: 빠르게 반복해서 락을 확인
Condition Variable: 특정 조건이 만족될 때까지 쓰레드 대기


(2) 스레드 풀(Thread Pool)

  • 필요할 때마다 새 쓰레드를 생성하는 것은 비효율적이므로, 미리 생성된 쓰레드 그룹을 사용.
  • 요청이 오면 대기 중인 쓰레드가 작업을 수행하고, 완료 후 다시 대기 상태로 돌아감.

➡ 스레드 풀을 활용하면?
스레드 생성 및 제거 비용 감소
CPU 리소스 활용 최적화


profile
李家네_공부방

0개의 댓글