Skip to content
败犬日报 2026-03-09

败犬日报 2026-03-09

1. stop_callback 谁来执行

cpp
#include <print>
#include <stop_token>
#include <thread>

using namespace std::literals;

void task(std::stop_token token, int num) {
    auto id = std::this_thread::get_id();
    std::println("call task({})", num);

    std::stop_callback cb1{token, [num, id] -> void {
                               std::println("- STOP1 requested in task({}, {})", num, id == std::this_thread::get_id());
                           }};
    std::this_thread::sleep_for(9ms);

    std::stop_callback cb2{token, [num, id] -> void {
                               std::println("- STOP2 requested in task({}, {})", num, id == std::this_thread::get_id());
                           }};
    std::this_thread::sleep_for(4ms);
}

int main() {
    std::jthread thread{[](std::stop_token token) -> void {
        for (int i = 0; i < 2; i++) task(token, i);
    }};

    std::this_thread::sleep_for(20ms);
    std::println();
}

输出是:

text
call task(0)
call task(1)

- STOP1 requested in task(1, false)
- STOP2 requested in task(1, true)

首先第一个 task 执行时,stop_callback 直到析构也没有 request_stop(),所以不会执行 stop_callback。

第二个 task 执行时,主线程析构了 jthread,此时就会 request_stop() 然后 join()。这个动作正好发生在 cb1 构造后 cb2 构造前。

https://zh.cppreference.com/w/cpp/thread/stop_callback.html:

Callback functions registered via stop_callback's constructor are invoked either in the same thread that successfully invokes request_stop() for a std::stop_source of the stop_callback's associated std::stop_token; or if stop has already been requested prior to the constructor's registration, then the callback is invoked in the thread constructing the stop_callback.

意思是构造结束的 stop_callback 会在发起 request_stop() 的线程调用。request_stop() 后的 stop_callback 会在这个线程直接执行。

所以就能看到输出 false, true。