(C++) thread

Posted by : at

Category : Cpp


STL thread의 목적

기존에 OS별 별도로 돌던 thead를 하나로 합쳐보자!
단, C++표준이기에 모든 OS에서 돌아가게 만들었다.
그에 따른 쓰기 불편한 점이 몇 가지 존재한다..


기존의 Thread 정리

얼마나 불편했는지 보자

// Windwos
#include <Windows.h>

DWORD WINAPI PrintMessage()
{
    // ...
}

int main() {
    DWORD myThreadID;

    HANDLE myHandle = CreateThread(0, 0, PrintMessage, NULL, 0, &myThreadID);

    WaitForSingleObject(myHandle, INFINITE);
    // thread가 종료될때 까지 기다린다.

    CloseHandle(myHandle);

    return 0;
}
// POSIX(pthread)
#include <pthread.h>

void *printMessage()
{
    // ...
}

int main() {
    pthread_t thread = 0;

    int result_code = pthread_create(&thread, NULL, printMessage, NULL);
    result_code = pthread_join(thread, NULL);

    return 0;
}

사용자는 이걸 다 알아야 한다.

C++11 전까지 표준 멀티쓰레딩 라이브러리가 없음
OS마다 멀티쓰레딩 구현이 달랐음

  • 리눅스/유닉스 : POSIX(pthread)
  • 윈도우 쓰레드 - 윈도우에서 pthread를 사용할순 있음(ver 1003.1만) - 불편하네… 표준 Thread를 만들어 보자

thread 생성

#include <iostream>
#include <string>
#include <thread>

void PrintMessage(const std::string& message)
{
    std::cout << message << std::endl;
}

int main() {
    std::thread thread(PrintMessage, "Message from a child thread");
    
    PrintMessage("Waiting the child thread");

    // 현재 스레드에서 떼어 내기
    thread.detach();

    // 다시 붙이고 싶다면?
    if(thread.joinable())
    {
        thread.join();
    }

    return 0;
}
// 람다식 사용

#include <iostream>
#include <string>
#include <thread>


int main() {
    auto PrintMessage = [](const std::string& message)
    {
        std::cout << message << std::endl;
    };

    std::thread thread(PrintMessage, "Message from a child thread");
    
    PrintMessage("Waiting the child thread");

    thread.join();

    return 0;
}
// 람다식 스레드에 매개변수 넣기

#include <iostream>
#include <string>
#include <thread>
#include <vector>

int main() {
    std::vector<int> list(100, 1);
    int result = 0;

    std::thread thread([](const std::vector<int>& v, int& result)
    {
        for( auto item : v )
        {
            result += item;
        }
    }, list, std::ref(result));

    thread.join();

    std::cout << "Result: " << result << std::endl;

    return 0;
}

thread에 매개변수 넣기

#include <iostream>
#include <thread>
using namespace std;

void f1(int a, int b)
{

}

int main()
{
    thread t1(&f1, 1, 2);
    thread t2(bind(&f1, 1, 2));
    // 둘 다 동일한 표현이다.

    t1.join();
    t2.join();
}
int n = 10;
thread t1(&f1, 1, n);            // error
thread t1(&f1, 1, ref(n));       // ok
// thread 잠깐 정지

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

int main()
{
    thread::id id = this_thread::get_id();

    cout << id << endl;

    this_thread::sleep_for(3s);
    this_thread::sleep_until(chrono::system_clock::now()+3s);
    this_thread::yield();           // 다른 스레드에게 우선순위를 양보한다.
}
#include <iostream>
#include <thread>
using namespace std;

void foo()
{
    cout << "thread start" << endl;
    this_thread::sleep_for(2s);
    cout << "thread end" << endl;
}

int main()
{
    thread t(&foo);
    t.join();       // 스레드 종료를 대기
    // or
    // t.detach();
}
#include <iostream>
#include <thread>
using namespace std;

void f1() {}
void f2(int a) {}

struct Worker
{
    void Main() {}
};

struct Functor
{
    void operator()() {}
};

int main()
{
    thread t1(&f1);

    thread t2(&f2, 5);

    Worker w;
    thread t3(&Workder::Main, &w);

    Functor f;
    thread t4(f);

    thread t5([](){cout << "thread t5" << endl;});
}

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links