[Server] #15-3. 쓰레드 생성

메모리 영역과 쓰레드

멀티 쓰레드 환경에서 메모리 사용 방식을 살펴보자.

  • Code 영역: 실행할 프로그램의 코드가 저장되는데, 수정이 되지 않기 때문에 쓰레드 간 충돌 문제가 없다.
  • Stack 영역: 각 쓰레드는 고유한 스택을 가지고 있어 독립적으로 작동하기에 충돌 문제가 없다.
  • Heap 영역: 동적으로 할당된 메모리로, 여러 쓰레드가 공유해서 사용할 수 있다.
  • Data 영역: 전역 변수 및 정적 변수가 저장되며, 여러 쓰레드가 공유해서 사용할 수 있다.

Heap과 Data 영역은 여러 쓰레드가 공유하므로 경쟁 상태(Race Condition)가 발생할 위험이 있다.

  • 경쟁 상태(Race Condition)란?
    • 멀티 쓰레드 프로그래에서 여러 쓰레드가 공유 자원에 동시에 접근하여 수정하는 상황에서 발생하는 문제이다.
    • 여러 쓰레드가 공유 자원을 동시에 접근하면 오류가 발생할 수 있기 때문에 이를 방지하기 위해 Mutex, Atomic 변수, Lock 등의 동기화 기법이 필요하다.

쓰레드 생성 실습

헤더 파일

  • thread와 스레드를 담을 vector 헤더 파일을 include한다.
#include <iostream>
using namespace std;
#include <thread>
#include <vector>

HelloThread 함수

  • 각 쓰레드가 실행될 때 호출되는 함수이다.
  • 쓰레드 번호를 출력하는 무한 루프를 실행한다.
void HelloThread(int i)
{
    while (true)
    {
        cout << "Hello Thread!" << i << endl;
    }
}

main 함수

  • 쓰레드 생성
    • vector<thread>를 사용해 12개의 쓰레드를 생성하고 저장한다.
    • 각 쓰레드는 HelloThread(i) 함수를 실행한다.
vector<thread> threads;

for (int i = 0; i < 12; ++i)
{
    threads.push_back(thread(HelloThread, i));
}

 

  • 쓰레드 종료 처리
    • hardware_concurrency() 함수는 CPU 코어 개수를 반환한다.
      • CPU 코어보다 많은 쓰레드를 생성한다고 해서 프로그램이 더 빨라지지 않는다.
      • 보통 코어 개수만큼의 쓰레드가 적절한 성능을 보장한다.
    • t.join()을 호출하여 메인 쓰레드가 모든 자식 쓰레드의 종료를 기다리도록 설정한다. join()을 하지 않으면 메인 쓰레드가 종료되면서 프로그램이 비정상적으로 종료될 수 있다.
for (thread& t :threads)
{
    int a = t.hardware_concurrency();

    t.join();
}

실습 커밋


출처 Rookiss님 게임 프로그래머 입문 올인원

Categories:

Updated:

Leave a comment