You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:50:54