0
0
CppHow-ToBeginner · 4 min read

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 running function with 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_token to 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.