封装std::thread并实现is_running()方法的技术方案咨询
为std::thread封装is_running()方法(C++17实现)
按照你的需求,我们可以通过封装std::thread并配合std::atomic<bool>实现is_running()方法,完全基于标准C++17特性,且不会修改原有业务逻辑——核心思路就是用原子变量跟踪线程函数的执行状态:
实现方案
- 封装线程包装类,内部持有
std::thread对象和std::atomic<bool>类型的状态标记 - 在包装类的内部线程入口中,先原子性标记线程为运行状态,再调用用户传入的业务线程函数
- 业务函数执行完毕后,原子性将状态标记为停止
is_running()方法直接返回状态标记的当前值
代码示例
#include <thread> #include <atomic> #include <functional> #include <tuple> class ThreadWrapper { public: // 接收任意可调用对象作为线程函数 template<typename Func, typename... Args> explicit ThreadWrapper(Func&& func, Args&&... args) : running_(false) { // 包装线程入口,先标记运行状态,再执行用户逻辑 thread_ = std::thread([this, func = std::forward<Func>(func), args = std::make_tuple(std::forward<Args>(args)...)]() mutable { // 原子性设置运行状态:仅当当前为false时才设为true,避免重复启动 bool expected = false; if (running_.compare_exchange_strong(expected, true)) { // 执行用户传入的原始线程逻辑 std::apply(std::move(func), std::move(args)); // 线程函数执行完毕,标记为停止 running_.store(false, std::memory_order_release); } }); } // 禁止拷贝,支持移动 ThreadWrapper(const ThreadWrapper&) = delete; ThreadWrapper& operator=(const ThreadWrapper&) = delete; ThreadWrapper(ThreadWrapper&&) noexcept = default; ThreadWrapper& operator=(ThreadWrapper&&) noexcept = default; // 核心方法:is_running() bool is_running() const noexcept { // 用memory_order_acquire保证读取到最新的状态值 return running_.load(std::memory_order_acquire); } // 按需暴露原有std::thread的接口(不修改原有逻辑) void join() { if (thread_.joinable()) { thread_.join(); } } void detach() { if (thread_.joinable()) { thread_.detach(); } } ~ThreadWrapper() { // 此处根据原有框架的线程生命周期逻辑调整,示例默认join if (thread_.joinable()) { thread_.join(); } } private: std::thread thread_; std::atomic<bool> running_; };
关键细节说明
std::atomic<bool>确保状态标记的线程安全,避免竞态条件compare_exchange_strong用于原子性切换运行状态,防止线程被重复启动- 内存序
std::memory_order_release和std::memory_order_acquire保证状态更新的跨线程可见性 - 完全保留用户原有线程逻辑:仅在用户函数执行前后添加状态标记,业务代码无任何修改
内容的提问来源于stack exchange,提问作者James S
相关产品推荐
相关产品推荐

