Detailed Explanation of std::jthread Usage, including its design purpose, common usage patterns, cancellation mechanism, differences from std::thread, and examples suitable for multithreading scenarios (the issue of exiting a while loop is precisely its advantage).
1. What is std::jthread?
A thread class introduced in C++20, with core features:
✔ Automatic join to avoid crashes from forgetting to join
std::jthread automatically calls join() upon destruction (if the thread is joinable).
✔ Built-in “cancellable” mechanism (stop_token)
It can automatically inject a std::stop_token into the thread function to notify the thread to exit safely.
Why is it better than std::thread?
When using std::thread:
●You must manually join/detach
●There is no safe exit mechanism; you can only use a custom flag or atomic variable
●If you forget to join, it will terminate directly upon destruction
Whereas std::jthread automatically:
●joins on destruction
●provides cancellation requests (stop_source / stop_token)
2. Basic Usage
Most basic startup method
std::jthread t([]{<br /> std::cout << "Hello jthread\n";<br />});
It will automatically join when leaving the scope.
3. Using stop_token for safe exit (most important)
std::jthread allows the first parameter of the thread function to automatically receive a stop_token:
std::jthread worker([](std::stop_token stoken){<br /> while (!stoken.stop_requested()) {<br /> // Perform task<br /> std::this_thread::sleep_for(std::chrono::milliseconds(100));<br /> std::cout << "Working...\n";<br /> }<br /> std::cout << "Stopped.\n";<br />});
The main thread notifies to stop:
worker.request_stop(); // Notify the thread to exit
📌 Features
●stop_token is a non-blocking signal
●The thread will not forcefully exit; your code must check stop_requested()
4. More common example of “while loop automatic exit” (what you need)
You mentioned “there is a while loop in the thread function, hoping to exit flexibly”; jthread is designed for this.
std::jthread t([](std::stop_token st){<br /> while (!st.stop_requested()) {<br /> // do work<br /> std::cout << ".";<br /> std::this_thread::sleep_for(std::chrono::milliseconds(200));<br /> }<br /> std::cout << "Loop exit\n";<br />});<br /><br />// Exit after a while<br />std::this_thread::sleep_for(std::chrono::seconds(2));<br />t.request_stop();
5. With condition variables & interruptible waiting
stop_token supports interruptible waiting:
std::condition_variable_any cv;<br />std::mutex m;<br /><br />std::jthread t([&](std::stop_token st){<br /> std::unique_lock lock(m);<br /> while (!st.stop_requested()) {<br /> cv.wait(lock, st, []{ return false; }); <br /> // wait will automatically return when stop_requested() is true<br /> }<br />});
stop_token allows condition_variable to be safely interrupted.
6. Relationship between stop_source / stop_token (similar to cancel token)
| Role | Usage |
|---|---|
| std::stop_source | Send cancellation request |
| std::stop_token | Used by the thread to query cancellation status |
| std::stop_callback | Register callback to be called upon cancellation |
Example:
std::stop_source src;<br />std::stop_token tok = src.get_token();<br /><br />std::jthread t([tok](std::stop_token){<br /> while (!tok.stop_requested()) {<br /> // do work<br /> }<br />});<br /><br />src.request_stop();
7. Summary of std::jthread vs std::thread Comparison
| Feature | std::thread | std::jthread |
|---|---|---|
| Join on destruction? | ❌ No (will terminate) | ✔ Automatic join |
| Stopping mechanism | ❌ None | ✔ Built-in stop_token |
| Interrupt condition_variable | ❌ Not supported | ✔ Supports condition_variable_any |
| Safer | ❌ Easy to forget join | ✔ Automatic safe exit on destruction |
| C++ version | C++11 | C++20 |
std::jthread is essentially a safer alternative to std::thread.
8. Provide a practical example combined with familiar multithreaded I/O and network programming
For example: a background thread continuously reads data from a buffer queue:
std::jthread io_thread([&](std::stop_token st){<br /> while (!st.stop_requested()) {<br /> if (!queue.empty()) {<br /> auto data = queue.pop();<br /> process(data);<br /> } else {<br /> std::this_thread::sleep_for(10ms);<br /> }<br /> }<br /> cleanup();<br />});
To stop:
io_thread.request_stop();
This is very suitable for the I/O completion ports (IOCP), asynchronous file processing, and queue consumption scenarios you mentioned earlier.
9. Try to write std::jthread like this
Recommended writing style:
void run(std::stop_token stoken) {<br /> while (!stoken.stop_requested()) {<br /> do_work();<br /> }<br />}<br /><br />std::jthread t(&run);
10. Points to note
1.stop_token will not forcibly terminate the thread → the thread must cooperate to check
2.If the thread is in blocking I/O (reading files, network) → stop_token cannot interrupt, a platform-specific cancellation mechanism is needed
3.No need to use detach, jthread is already a safer join