std::jthread (C++20)란?
C++20부터 추가가 되었기 때문에 아직 범용적으로 사용되고 있지는 않다. std::thread의 단점을 어느정도 보완했는지 정도만 알면된다.
Example Code : 일반적인 thread를 사용하는 경우
void fn()
{
std::cout << "fn" << std::endl;
}
int main()
{
std::thread t1(fn);
//t1.join();
return 0;
}
일반적으로 std::thread는 join 또는 detach 하지 않으면 terminate가 call이 되면서 실행에러가 나타난다.
이를 해결하기 위해 std::jthread를 사용해본다.
Example Code : jthread를 사용하는 경우
void fn()
{
std::cout << "fn" << std::endl;
}
int main()
{
std::jthread t1(fn);
return 0;
}
std::jthread를 사용하면 join이 없음에도 프로세스가 정상적으로 실행되고 종료된다.
메모리 접근
그 이유는 main thread에서 jthread 오브젝트가 없어질 때 desctructor가 호출이 되는데 desctructor는 내부적으로 join 함수를 호출한다. 따라서, 일반적인 thread보다 더욱 안전하게 사용할 수 있다.
stop_token
또한, jthread는 stop_token을 argument로 가지고 있는 함수도 사용할 수 있는데 예시를 보자.
Example Code : 일반적인 thread 사용
void fn()
{
for (int i = 0; ; i++)
{
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
std::cout << i << std::endl;
}
}
int main()
{
std::thread t1(fn);
t1.join();
return 0;
}
위의 코드는 무한하게 1초간 기다리면서 i 값을 계속 출력한다. stop_token을 사용하면 이를 영원히 기다릴 필요 없다.
Example Code : stop_token 사용
void fn(std::stop_token stoken)
{
for (int i = 0; ; i++)
{
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
std::cout << i << std::endl;
if (stoken.stop_requested())
{
std::cout << "stop requested" << std::endl;
return;
}
}
}
int main()
{
std::jthread t1(fn);
t1.request_stop();
t1.join();
return 0;
}
0을 출력하고 바로 프로세스가 종료된다. 이는 main thread에서 stop을 request 해주었고 다른 thread에서는 stop_token을 통해서 폴링 방식으로 알아낸 것이다. 그리고 jthread 특성상 request_stop() 과 join()을 호출하지 않아도 같은 결과가 나오게 된다. 그 이유는 jthread는 destructor에서 request_stop()이 먼저 처리되고 join하는 방식으로 동작하기 때문이다.
폴링 방식
특정 주기마다 Thread를 돌면서 시그널이 들어오는지 확인하는 방식
'C++ > Thread' 카테고리의 다른 글
[Thread] std::mutex (0) | 2022.07.15 |
---|---|
[Thread] Mutex(뮤텍스) (0) | 2022.07.15 |
[Thread] thread_local (0) | 2022.06.20 |
[Thread] std::thread Argument (0) | 2022.06.20 |
[Thread] std::thread (0) | 2022.06.20 |