C++20 线程超时取消的简化机制
C++20 引入了 std::jthread 和 stop_token 机制,通过源码级设计实现了线程协作式取消的超时控制。以下是关键实现原理:
std::stop_token 与 std::stop_source 的协作
std::stop_token 提供线程安全的取消信号检查接口,其内部通过 std::atomic<bool> 标记状态:
class stop_token {
std::shared_ptr<__stop_state> _state; // 共享状态
public:
bool stop_requested() const noexcept {
return _state && _state->_stop_requested.load();
}
};
std::stop_source 通过修改同一共享状态触发取消:
class stop_source {
std::shared_ptr<__stop_state> _state;
public:
void request_stop() {
if (_state && !_state->_stop_requested.exchange(true))
_state->_notify_callbacks(); // 触发回调链
}
};
std::jthread 的自动资源管理
std::jthread 在析构时自动调用 request_stop() 并执行 join(),其构造函数绑定 stop_token 到线程函数:
template<typename Callable>
jthread::jthread(Callable&& f) {
_stop_source = std::stop_source();
_thread = std::thread([token = _stop_source.get_token(), f = std::forward<Callable>(f)] {
if constexpr (requires { f(token); }) {
f(token); // 传递 stop_token 给可调用对象
} else {
f();
}
});
}
超时控制的实现模式
线程函数可通过轮询或回调响应取消请求:
void worker(std::stop_token token) {
while (!token.stop_requested()) {
// 执行任务
std::this_thread::sleep_for(100ms);
}
// 清理资源
}
超时触发示例:
std::jthread job(worker);
std::stop_source = job.get_stop_source();
std::this_thread::sleep_for(2s);
source.request_stop(); // 超时取消
与传统方法的对比
相较于 C++11 的 std::thread + 条件变量方案,C++20 方案的优势在于:
- 无需手动维护
atomic<bool>标志位 - 消除线程分离(detach)导致的资源泄漏风险
- 提供标准化的取消通知机制
源码级实现可见 libstdc++ 的 <thread> 头文件,其核心是通过共享状态对象的引用计数管理生命周期。