无法使用stop_token停止jthread的问题求助
C++20 jthread request_stop无法终止线程的解决方案
问题描述
我是一名业余开发者,之前学过C但需要定期复习,目前正在学习C20的std::jthread和关联的std::stop_token机制。在VS2022(已设置语言标准为C++20)中成功启动了线程,但调用request_stop()后无法停止线程,主线程执行完毕后子线程仍在运行,代码如下:
#include <iostream> #include <chrono> #include <thread> #include <functional> class Testing { int updates{ 0 }; public: void update(std::stop_token s, int i, char l) { while (!s.stop_requested()) { updates++; std::cout << updates << " " << l << "\n"; std::this_thread::sleep_for(std::chrono::milliseconds(i)); } std::cout << l << " stopped\n"; } }; int main() { Testing test_1, test_2; std::stop_token s_1, s_2; std::jthread t_1(&Testing::update, &test_1, s_1, 2300, 'A'); std::jthread t_2(&Testing::update, &test_2, s_2, 700, 'B'); std::this_thread::sleep_for(std::chrono::milliseconds(10000)); std::cout << "Main thread done\n"; t_1.request_stop(); if (t_1.joinable()) { t_1.join(); } t_2.request_stop(); if (t_2.joinable()) { t_2.join(); } return 0; }
问题原因
你手动创建的std::stop_token(s_1、s_2)是独立的空令牌,没有和std::jthread内部的停止源(std::stop_source)绑定。调用t_1.request_stop()只会触发jthread自身停止源的停止请求,但线程函数里检测的是你手动传递的、无关联的stop_token,自然不会响应停止信号。
修正方案
std::jthread的核心特性之一就是自动管理停止令牌:它会在构造时生成一个stop_source,并将其关联的stop_token自动作为第一个参数传递给线程函数(只要线程函数的第一个参数是std::stop_token类型)。你不需要手动创建和传递stop_token。
修正后的代码:
#include <iostream> #include <chrono> #include <thread> #include <functional> class Testing { int updates{ 0 }; public: void update(std::stop_token s, int i, char l) { while (!s.stop_requested()) { updates++; std::cout << updates << " " << l << "\n"; std::this_thread::sleep_for(std::chrono::milliseconds(i)); } std::cout << l << " stopped\n"; } }; int main() { Testing test_1, test_2; // 移除手动创建的stop_token,让jthread自动传递关联的令牌 std::jthread t_1(&Testing::update, &test_1, 2300, 'A'); std::jthread t_2(&Testing::update, &test_2, 700, 'B'); std::this_thread::sleep_for(std::chrono::milliseconds(10000)); std::cout << "Main thread done\n"; t_1.request_stop(); t_1.join(); // 显式join更清晰,jthread析构时也会自动join t_2.request_stop(); t_2.join(); return 0; }
额外说明
- 如果你需要手动控制停止源(比如让多个线程共享同一个停止信号),可以先创建
std::stop_source,再通过它获取stop_token传递给jthread,但这种场景是少数。 std::jthread在析构时会自动调用request_stop()并join线程,所以即使你不写显式的request_stop和join,程序也能正常退出,但显式调用可以更明确地控制线程的停止时机。
内容的提问来源于stack exchange,提问作者Radiobiscuit
相关产品推荐
相关产品推荐

