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

非std::atomic场景下,实现线程安全且noexcept的ValueCopier类方案探究

让ValueCopier实现线程安全并保留noexcept属性的可行方案?

原始无线程安全的ValueCopier类

#include <type_traits>

template<typename T>
requires std::is_nothrow_copy_constructible_v<T>
      && std::is_nothrow_copy_assignable_v<T>
class ValueCopier
{
public:
    // Constructor
    ValueCopier(T const& object) noexcept
      : _object{object}
    {
        // Do nothing
    }

    // Return a copy of a stored object
    T getCopy() const noexcept
    {
        return _object;
    }

    // Change the stored object
    void setValue(T const& object) noexcept
    {
        _object = object;
    }

private:
    T _object;
};

核心问题:能否让该类实现线程安全的同时,保持所有函数的noexcept属性?


方案一:使用std::atomic实现线程安全

#include <atomic>
#include <type_traits>

template<typename T>
requires std::is_nothrow_copy_constructible_v<T>
      && std::is_nothrow_copy_assignable_v<T>
class ValueCopier
{
public:
    // Constructor
    ValueCopier(T const& object) noexcept
      : _object{object}
    {
        // Do nothing
    }

    // Return a copy of a stored object
    T getCopy() const noexcept
    {
        return _object.load();
    }

    // Change the stored object
    void setValue(T const& object) noexcept
    {
        _object.store(object);
    }

private:
    std::atomic<T> _object;
};

局限性:std::atomic仅支持平凡可复制类型,导致该类无法适配非平凡可复制的类型,适用范围大幅受限。


方案二:使用std::mutex实现线程安全

#include <mutex>
#include <type_traits>

template<typename T>
requires std::is_nothrow_copy_constructible_v<T>
      && std::is_nothrow_copy_assignable_v<T>
class ValueCopier
{
public:
    // Constructor
    ValueCopier(T const& object) noexcept
      : _object{object}
    {
        // Do nothing
    }

    // Return a copy of a stored object
    T getCopy() const // Not noexcept
    {
        auto const lock = std::lock_guard<std::mutex>(_mutex);
        return _object;
    }

    // Change the stored object
    void setValue(T const& object) // Not noexcept
    {
        auto const lock = std::lock_guard<std::mutex>(_mutex);
        _object = object;
    }

private:
    mutable std::mutex _mutex;
    T _object;
};

局限性:std::lock_guard的构造(即加锁操作)可能抛出异常,导致getCopy()和setValue()无法保留noexcept属性,违背需求。


疑问

是否存在遗漏的可行方案?比如有没有能保证mutex加锁不抛出的前置条件?或者其他同步机制可以同时满足线程安全和noexcept要求?理论上基于std::atomic<bool>的自旋锁可以实现noexcept,但这种方式会持续占用CPU资源,并非理想选择。

内容的提问来源于stack exchange,提问作者Eternal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:47:33