How to Use std::jthread in C++20 for Thread Management
Use
std::jthread in C++20 to create threads that automatically join when they go out of scope, preventing common threading bugs. You can start a thread by passing a callable to std::jthread and use its built-in stop token to request thread cancellation safely.Syntax
The basic syntax to create a std::jthread is to construct it with a callable (function, lambda, or functor). It automatically joins on destruction, so you don't need to call join() manually.
You can also use the stop token passed to the thread function to check for stop requests.
std::jthread t(function, args...);- starts a thread runningfunctionwith arguments.t.request_stop();- requests the thread to stop.t.get_stop_token()- obtains a token to check for stop requests inside the thread.
cpp
std::jthread t([](std::stop_token st){
while (!st.stop_requested()) {
// thread work
}
});Example
This example shows how to create a std::jthread that prints a message every second and stops when requested.
cpp
#include <iostream> #include <thread> #include <chrono> #include <stop_token> void print_messages(std::stop_token st) { while (!st.stop_requested()) { std::cout << "Working..." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cout << "Thread stopping." << std::endl; } int main() { std::jthread worker(print_messages); std::this_thread::sleep_for(std::chrono::seconds(3)); worker.request_stop(); // No need to call join(), jthread joins automatically return 0; }
Output
Working...
Working...
Working...
Thread stopping.
Common Pitfalls
Common mistakes when using std::jthread include:
- Not using the stop token inside the thread function, which means the thread won't stop when requested.
- Trying to manually join or detach the
std::jthread, which is unnecessary and can cause errors. - Passing arguments incorrectly to the thread function.
Always design your thread function to periodically check the stop token to exit cleanly.
cpp
/* Wrong way: ignoring stop token and manually joining */ #include <thread> #include <iostream> void work() { while (true) { std::cout << "Working..." << std::endl; } } int main() { std::jthread t(work); // t.join(); // Not needed and will cause compile error return 0; } /* Right way: use stop token */ #include <iostream> #include <thread> #include <stop_token> void work(std::stop_token st) { while (!st.stop_requested()) { std::cout << "Working..." << std::endl; } } int main() { std::jthread t(work); t.request_stop(); return 0; }
Quick Reference
- std::jthread: Thread class that joins automatically on destruction.
- request_stop(): Ask the thread to stop.
- get_stop_token(): Get token to check stop requests inside thread.
- Thread function: Accepts
std::stop_tokento support cooperative cancellation.
Key Takeaways
Use std::jthread to create threads that automatically join when done, avoiding detach/join mistakes.
Pass a std::stop_token to your thread function to support safe cooperative stopping.
Call request_stop() on the jthread to ask the thread to stop its work.
Do not manually call join() or detach() on std::jthread; it handles joining automatically.
Design thread loops to periodically check stop_requested() to exit cleanly.