败犬日报 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。