不能。std::stop_token 仅提供协作式中断机制,线程需主动轮询或等待该 token 并自行退出;C++20 不支持强制终止线程,必须配合 std::jthread、std::stop_token 和 stop_callback 或轮询 stop_requested() 实现安全中断。

std::stop_token 能否直接终止正在运行的线程?
不能。std::stop_token 本身不终止线程,它只提供一种协作式中断机制:线程需主动轮询或等待该 token,并在收到停止请求后自行退出。C++20 没有提供强制杀线程的接口(如 pthread_cancel 或旧式 std::thread::kill),这是刻意设计的安全约束。
如何用 std::stop_token 实现安全的线程中断?
核心是三件套配合:std::jthread(自动注册 stop_source)、std::stop_token(传入线程函数)、std::stop_callback 或轮询 stop_token.stop_requested()。推荐优先使用 std::jthread,它比 std::thread 更安全、更简洁。
-
std::jthread构造时自动关联一个std::stop_source,析构时自动调用request_stop()(可禁用) - 线程函数参数中接收
std::stop_token,用于检查中断状态 - 避免在循环中无休止忙等;应在可能阻塞点(如
sleep_for、wait、read)插入轮询或使用支持 stop_token 的等待函数(如std::condition_variable::wait重载)
#include#include #include void worker(std::stop_token stoken) { for (int i = 0; i < 10; ++i) { if (stoken.stop_requested()) { std::cout << "worker: stopping early at " << i << "\n"; return; } std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::cout << "worker: step " << i << "\n"; } } int main() { std::jthread t{worker}; std::this_thread::sleep_for(std::chrono::milliseconds(700)); t.request_stop(); // 主动触发停止 // t.join(); // jthread 析构会自动 join,除非已 detach }
std::stop_token 在条件变量等待中怎么用?
直接传入 std::condition_variable::wait 的重载版本,它会在被唤醒或收到 stop 请求时返回,并通过 stop_token.stop_requested() 判断原因。这是比手动轮询更高效、更及时的中断方式。
- 必须使用支持
stop_token的wait重载(签名含std::stop_token参数) - 该重载内部会注册临时回调,确保即使等待被虚假唤醒也能响应中断
- 返回后应先检查
stoken.stop_requested(),再处理条件逻辑,避免漏掉中断信号
#include#include #include #include std::mutex mtx; std::condition_variable cv; bool ready = false; void waiter(std::stop_token stoken) { std::unique_lock lk{mtx}; // 等待 ready 为 true,或 stop 请求到来 cv.wait(lk, stoken, []{ return ready; }); if (stoken.stop_requested()) { std::cout << "waiter: interrupted before ready\n"; return; } std::cout << "waiter: ready is true\n"; }
常见错误:把 stop_token 当成“取消句柄”滥用
有人试图在线程外反复调用 stop_source.request_stop() 多次,或在已停止的 token 上做无效轮询,这不会报错但毫无意义——stop_requested() 一旦为 true 就永远为 true,且多次 request_stop 是幂等的。真正容易出问题的是:
立即学习“C++免费学习笔记(深入)”;
- 在线程函数中未接收
std::stop_token参数,导致完全无法响应中断 - 使用
std::thread却没手动管理std::stop_source,造成 token 始终无效 - 在 long-running 计算循环中不轮询,导致中断延迟数秒甚至更久
- 误以为
std::jthread::request_stop()会立即暂停执行——它只是发信号,线程何时响应取决于你代码里哪里检查
协作式中断的关键不在 token 本身,而在于你是否在合理位置埋了检查点。没有检查,token 就是张废纸。











