C++ 쓰레드

Windows IOCP기반 Stateful Server 구현에 관한 학습 내용을 정리한 것입니다. Linux OS 및 epoll 기반의 서버 구현과는 다소 차이점이 있을 수 있습니다.

쓰레드 기본

  • 하나의 프로세스는 여러개의 쓰레드로 분리할 수 있다.
  • 쓰레드는 같은 프로세스 내의 힙과 데이터 영역을 공유하고, 개별적인 스택영역을 갖는다.
  • TCB를 통해 관리된다.
  • CPU 코어 개수 = 쓰레드의 개수 일 때 가장 이상적(ideal)임.

<thread> api

Type.h를 통해 타입의 이름이 변경된 부분이 있습니다.
예) int32, int64, …

#include <iostream>
#include <thread> //쓰레드 라이브러리 추가

void HelloThread() //쓰레드 테스트용 함수
{
    cout << "Hello Thread!" << endl;
}

int main()
{
    std::thread t; //쓰레드를 먼저 선언할 수 있음. 메모리는 할당되지만 실행하지 않는 상태.
    
    auto id1 = t.get_id(); // 쓰레드에 작업이 지정되지 않았으므로 유효하지 않은 쓰레드, id = 0
    cout << "id1: " << id1 << endl;
    t = std::thread(HelloThread);
    
    auto id2 = t.get_id(); // 작업이 분배됨. 0이 아닌 유일성 id 할당.
    cout << "id2: " << id2 << endl;
    
    int32 count = t.hardware_concurrency(); //CPU 코어 개수확인
    cout << "core amount: " << count << endl;
    
    //t.detach();
    
    cout << "Hello Main!" << endl;
    
    if(t.joinable())
        t.join();
    
    return 0;
}    
  • get_id() : 쓰레드의 id 확인, 유효하지 않은 쓰레드는 0
  • hardware_concurrency() : 사용 가능한 CPU 코어 개수 확인
  • detach() : 쓰레드를 stb::thread 객체에서 분리. 더 이상 join할 필요 없음
    • linux의 데몬 프로세스와 유사함.
  • joinable() : 해당 쓰레드가 join 가능한 상태인지 확인.
  • join() : 쓰레드 종료를 기다림

인자가 있는 쓰레드

#include <iostream>
#include <thread>
void HelloThread(int32 num)
{
    cout << num << endl;
}

void main()
{
    vector<std::thread> v;
    
    for(int32 i = 0 ; i < 10 ; i++)
    {
        v.push_back(std::thread(HelloThread), i);
    }
    
    for(int32 i = 0 ; i < 10 ; i++)
    {
        if(v[i].joinable())
        {
            v[i].join();
            cout << i << " joined" << endl;
        }
    }
}

실행결과

10

5
3
8
2
67

4
9
0 joined
1 joined
2 joined
3 joined
4 joined
5 joined
6 joined
7 joined
8 joined
9 joined
  • 쓰레드 실행 순서는 보장되지 않음
  • 원자성이 요구될때 지켜줘야함.