如何在std::jthread线程函数中获取stop_token?
Great question! The confusion here comes from not leveraging one of the key design features of std::jthread: it automatically passes its associated std::stop_token to the thread function if the function accepts it as a parameter. Here's how to fix your code:
Correct Implementation
The simplest and most idiomatic way to get the stop_token is to define your thread lambda to accept a const std::stop_token& as an argument. std::jthread will handle passing its internal token to this function automatically:
#include <chrono> #include <condition_variable> #include <mutex> #include <thread> template<typename Rep, typename Period> void sleep_for(const std::chrono::duration<Rep, Period>& d, const std::stop_token& token) { std::condition_variable cv; std::mutex mutex; std::unique_lock<std::mutex> lock{ mutex }; std::stop_callback stop_wait{ token, [&cv]() { cv.notify_one(); } }; cv.wait_for(lock, d, [&token]() { return token.stop_requested(); }); } int main() { // The lambda now accepts the stop_token passed by jthread std::jthread t([](const std::stop_token& thread_stop_token) { sleep_for(std::chrono::seconds(5), thread_stop_token); }); std::this_thread::sleep_for(std::chrono::seconds(1)); t.request_stop(); // Triggers the stop_token in the child thread return 0; }
Why Your Original Attempt Didn't Work
std::this_jthread::get_stop_token() isn't valid C++ syntax—there's no std::this_jthread namespace or class in the standard library. While you could use std::this_thread::get_stop_token() (available in C++20) to retrieve the token for the current thread, this is less explicit and relies on the thread being associated with a stop source (which jthread does set up).
The parameter-passing approach is preferred because:
- It makes the thread's cancelability explicit in the function signature
- It avoids relying on implicit thread state
- It aligns with the intended design of
std::jthread, which was created to simplify thread cancellation workflows
How This Fix Works
When you start a std::jthread, it creates an internal std::stop_source. When you define your thread function to accept a stop_token, the jthread constructor automatically extracts the token from its stop_source and passes it to the function when the thread starts.
When you call t.request_stop() in the main thread, it triggers the stop source, which marks the token as requested. Your sleep_for function's std::stop_callback detects this and notifies the condition variable, waking up the wait_for call immediately—so your program exits in roughly 1 second as expected.
内容的提问来源于stack exchange,提问作者Dmitriano

