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

为何C++标准库未提供类似timed_mutex的atomic::try_load_for与try_store_for?

为什么C++标准库未提供带超时机制的原子类型?

我开发了一款需响应安全关键事件的程序,必须保证循环内的执行进度,因此要求循环内所有函数调用都带有超时机制,同时需要使用原子数据类型。std::atomic<my_struct>本可满足需求,但它并没有类似try_lock_for的函数。我自己实现了一个带超时的原子包装类(代码如下),想知道为何C++标准库至今未提供这类功能?

#ifndef TIMED_ATOMIC_HPP
#define TIMED_ATOMIC_HPP

#include <mutex>
#include <chrono>
#include <expected>
#include <memory>
#include <type_traits>

template<typename T>
struct is_shared_ptr : std::false_type {};

template <typename U>
struct is_shared_ptr<std::shared_ptr<U>> : std::true_type {};

template <typename T>
struct is_unique_ptr : std::false_type {};

template <typename U, typename D>
struct is_unique_ptr<std::unique_ptr<U, D>> : std::true_type {};

template <typename T>
struct is_raw_pointer : std::is_pointer<T> {};

template <typename T>
concept NotPointerType = !is_raw_pointer<T>::value && !is_unique_ptr<T>::value && !is_shared_ptr<T>::value;

template<typename T>
concept AllowedType = NotPointerType<T> && std::is_copy_constructible_v<T> && std::is_move_constructible_v<T>;

/// @brief Wrapper class to allow threadsafe access with a timeout. This is required because the robot state update thread should never hang because it is responsible for stopping the robot in case exit_flag is set.
template<typename T>
requires AllowedType<T>
class timed_atomic {
    private:
        std::timed_mutex mtx {};
        T value {};

    public:
        explicit timed_atomic(T initial_value) : value{initial_value} {}
        timed_atomic() = default;

        std::expected<T, std::monostate> try_load_for(std::chrono::microseconds timeout_us) {
            std::unique_lock lock{mtx, std::defer_lock};
            if(!lock.try_lock_for(timeout_us)) {
                return std::unexpected{std::monostate{}};
            }
            return value;
        }

        bool try_store_for(T new_value, std::chrono::microseconds timeout_us) {
            std::unique_lock lock{mtx, std::defer_lock};
            if(!lock.try_lock_for(timeout_us)) {
                return false;
            }
            value = std::move(new_value);
            return true;
        }
};

#endif

我曾查找过类似timed_mutex的std::atomic::try_lock_for相关内容,找到了《C++20: How to wait on an atomic object with timeout?》,但其中的wait函数并非我所需。

补充说明:更多上下文可参考《"Real-time" multithreaded design with timeouts》,中文译名为《带有超时的“实时”多线程设计》


核心原因:原子类型与超时锁的设计目标本质冲突

std::atomic的设计初衷是利用硬件原子指令实现无锁、低延迟的内存同步,它的所有操作都是直接映射到CPU的原子指令(比如lock cmpxchg),全程不需要操作系统内核介入,保证了极致的性能和确定性。而try_lock_for这类超时机制是互斥锁的特性,依赖操作系统的线程调度来阻塞/唤醒线程,本质是一种阻塞式同步,和原子类型的“无锁、轻量”设计哲学完全相悖。

C++标准库刻意保持std::atomic的极简性,只暴露硬件原生支持的原子操作——如果把超时等待这类需要内核参与的逻辑塞进原子类型,会彻底改变它的定位,让它变成一个“披着原子外衣的互斥锁”,混淆了两种完全不同的同步模型。

关于C++20的atomic::wait

你提到的C++20原子wait函数,它的定位是替代忙等待的通知机制:当原子值未达到预期时,线程可以进入休眠,直到其他线程修改原子值并通知它。它并不提供对原子数据的独占访问锁定,因此确实不符合你需要的“带超时的读写控制”场景。

你的自定义实现是合理的选择

你实现的timed_atomic本质是用std::timed_mutex包装数据,提供带超时的线程安全读写,这在安全关键的实时场景下完全合理——它既保证了数据访问的线程安全,又能避免线程无限阻塞,符合你对循环执行进度的要求。标准库没有提供这类封装,是因为这类需求属于“特定场景下的同步封装”,标准库更倾向于提供基础组件(比如timed_mutex、atomic),让开发者根据需求组合实现,而不是覆盖所有细分场景。


内容的提问来源于Stack Exchange,提问作者Hans Müller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:23:13