CodeNote
Coding Note
CodeNote
전체 방문자
오늘
어제
  • 전체 보기 (35)
    • C++ (33)
      • Modern C++ (12)
      • Modern C++ STL (0)
      • Thread (16)
      • Thread (Async) (5)
    • 디자인패턴 (0)
    • Algorithm (2)
    • Electron (0)
    • Python (0)

블로그 메뉴

  • 홈
  • Github
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Free
  • C++
  • mutex
  • LOCK
  • 자료구조
  • C++ #Memory

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
CodeNote

Coding Note

[Thread] std::thread
C++/Thread

[Thread] std::thread

2022. 6. 20. 16:50

std::thread

thread에 대한 기본적인 내용부터 알아본다.

Constructor

cppreference std::thread constructor

Constructor를 보면 Thread를 동작시키기 위해서는 3번째 정의처럼 함수를 같이 넘겨줘야한다.

또한, Move Constructor는 정의가 되어있는 반면 Copy Constructor는 삭제되어있는걸 볼 수 있다. 

 

Example Code

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

void fn()
{
    std::cout << "Fn" << std::endl;
}

int main()
{
    std::thread t1(fn);
    std::thread t2(std::move(t1));
    t2.join();
    
    return 0;
}

그렇기 때문에 위의 코드에서는 L-Value를 R-Value로 변경해주는 std::move 를 통해 t2를 생성할 수 있다.

즉,  실제 Thread가 활성화될 수 있도록 생성할 때는 t1처럼 함수를 같이 던져주거나 t2처럼 Move를 통한 생성만 가능하다는 것이다.

 

Destructor

thread destructor

Thread는 joinable한 상태이면 종료 함수인 std::terminate()가 호출된다.

 

Example Code : Join이 있을 경우

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

void fn()
{
    std::cout << "Fn" << std::endl;
}

int main()
{
    std::thread t1(fn);
    t1.join();

    std::cout << "joinable:" << t1.joinable() << std::endl;
    
    return 0;
}

출력 결과

Thread(t1)이 먼저 join이 되어 joinable 상태가 false가 된다. 이 후 destructor가 불렸기 때문에 잘 종료가 된 것이다.

메인 스레드는 스레드 t1이 join이 되길 기다리고 t1이 성공적으로 join이 된 후에 해당 스레드 오브젝트를 삭제하기 때문에 아무런 문제가 없이 잘 종료가 된다.

 

Example Code : Join이 없을 경우

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

void fn()
{
    std::cout << "fn" << std::endl;
}

int main()
{
    std::thread t1(fn);
    
    return 0;
}

함수 fn을 다른 Thread에서 실행하고 해당 Thread가 join이 되지 않았는데 main함수가 끝나버린다. 그 뒤에 Thread destructor가 실행이 되면서 문제가 일어난다.

그림으로 보면 t1 스레드가 마무리되기도 전에 main함수가 종료가 되었고 t1 오브젝트를 없애려고한다.

이 때 joinable은 true기 때문에 terminate 함수를 호출하게 되는 것이다.

 

detach

detach에 대한 예제 코드를 보자.

Example Code

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

void fn()
{
    std::cout << "fn" << std::endl;
}

void threadCaller()
{
    std::thread t1(fn);
    t1.detach();
}

int main()
{
    threadCaller();
    
    return 0;
}

 

메모리 접근

Memory View

실행 과정

위 코드에 대한 내용을 순차적으로 보면 다음과 같다.

  1. main 함수부터 threadCaller 함수를 실행시킨다.
  2. threadCaller함수 안에서 thread를 생성하고 함수 fn을 실행한다.
  3. 이 상태에서 detach를 하면 thread 오브젝트와 분리한다.
  4. threadCaller 함수가 끝나면서 Stack에서 해제된다.

fn을 실행시키고 있는 Thread는 계속해서 일을 진행할 수 있다. 그렇지만 실제로는 detach는 사용하지 않는 것이 좋다. 그 이유는 끊어진 Thread는 다시 Main Thread과 통신하기가 어렵기 때문이다.

'C++ > Thread' 카테고리의 다른 글

[Thread] Mutex(뮤텍스)  (0) 2022.07.15
[Thread] std::jthread (조이닝 쓰레드)  (0) 2022.07.13
[Thread] thread_local  (0) 2022.06.20
[Thread] std::thread Argument  (0) 2022.06.20
[Thread] Introduction  (0) 2022.06.13
    'C++/Thread' 카테고리의 다른 글
    • [Thread] std::jthread (조이닝 쓰레드)
    • [Thread] thread_local
    • [Thread] std::thread Argument
    • [Thread] Introduction
    CodeNote
    CodeNote
    기록 블로그

    티스토리툴바