首页 > 后端开发 > C++ > 正文

c++如何实现一个简单的软件事务内存(STM)_c++并发控制新思路【实验性】

裘德小鎮的故事
发布: 2025-12-14 13:23:02
原创
474人浏览过
用C++可实现轻量级STM,核心是版本号验证+本地日志+提交时冲突检测,读路径无锁、乐观并发,适合教学与嵌入式场景,但需手动管理读写集且非生产就绪。

c++如何实现一个简单的软件事务内存(stm)_c++并发控制新思路【实验性】

用 C++ 实现一个“简单但可用”的软件事务内存(STM)是完全可行的,核心不在于替代工业级方案(如 libcdsTL2),而在于理解 STM 的关键机制:读写隔离、冲突检测、原子提交与回滚。下面是一个轻量、无锁(读路径无锁)、基于乐观并发的实验性 STM 实现思路,适合学习和小规模嵌入式/教学场景。

核心设计:版本化 + 本地缓存 + 提交时验证

每个共享变量附加一个全局递增的版本号(version_t),事务执行时:

  • 读操作:记录变量当前版本号,并缓存其值(避免重复读)
  • 写操作:只写入事务私有日志(write_log),不直接修改原变量
  • 提交前:遍历所有读集,检查对应变量版本是否未变;若全部通过,再按顺序将写日志原子写入,并 bump 全局版本
  • 失败则丢弃日志,重试(可加退避)

关键组件实现(C++17 风格)

以下为最小可行代码骨架(省略异常安全与内存序细节,实际需补充):

struct versioned_value {
    mutable std::atomic<size_t> version{0};
    mutable std::mutex mtx;
    std::any data;
<pre class='brush:php;toolbar:false;'>template<typename T>
T read() const {
    std::shared_lock<std::shared_mutex> lock(mtx);
    return std::any_cast<T>(data);
}

template<typename T>
void write(const T& v) {
    std::unique_lock<std::shared_mutex> lock(mtx);
    data = v;
    version.fetch_add(1, std::memory_order_relaxed);
}
登录后复制

};

立即学习C++免费学习笔记(深入)”;

短影AI
短影AI

长视频一键生成精彩短视频

短影AI 170
查看详情 短影AI

struct transaction { struct read_entry { size_t key; size_t ver; std::any val; }; struct write_entry { size_t key; std::any val; };

std::vector<read_entry> reads;
std::vector<write_entry> writes;
static inline std::atomic<size_t> global_clock{0};

bool commit(std::vector<versioned_value*>& shared_vars) {
    // Step 1: validate all reads
    for (auto& r : reads) {
        if (shared_vars[r.key]->version.load(std::memory_order_acquire) != r.ver)
            return false;
    }
    // Step 2: install writes (with bumped version)
    for (auto& w : writes) {
        shared_vars[w.key]->write(w.val);
    }
    return true;
}
登录后复制

};

立即学习C++免费学习笔记(深入)”;

使用方式:类似数据库的 try-commit 模式

用户不直接访问变量,而是包裹在事务块中:

// 假设有两个共享变量
versioned_value x, y;
std::vector<versioned_value*> vars = {&x, &y};
<p>for (int retry = 0; retry < 10; ++retry) {
transaction t;
// 读取并记录版本
t.reads.push_back({0, x.version.load(), x.read<int>()});
t.reads.push_back({1, y.version.load(), y.read<int>()});</p><pre class='brush:php;toolbar:false;'>// 计算新值(纯内存操作)
int nx = std::any_cast<int>(t.reads[0].val) + 1;
int ny = std::any_cast<int>(t.reads[1].val) * 2;

// 写入日志(不改原值)
t.writes.push_back({0, nx});
t.writes.push_back({1, ny});

if (t.commit(vars)) {
    break; // success
}
std::this_thread::yield(); // or backoff
登录后复制

}

注意事项与局限性

这个实验性 STM 是教学导向,不是生产就绪方案:

  • 无自动读写集跟踪:需手动构造 reads/writes,真实 STM 通常靠重载 operator[] 或宏注入
  • 无内存回收:std::any 可能引发分配,且未处理 ABA 或对象生命周期问题
  • 写冲突串行化:多个事务写同一变量时,后提交者必然失败,可能饥饿
  • 不支持嵌套事务、abort handler、持久化等高级特性

但它清晰暴露了 STM 的本质:**把并发控制从“互斥”转向“验证+重试”,把一致性保障移到提交点**。

基本上就这些。想扩展?可以加读写锁优化读多写少场景,或用 hazard pointer 管理内存,甚至对接 std::jthreadstd::stop_token 支持取消。实验性,贵在动手拆解。

以上就是c++++如何实现一个简单的软件事务内存(STM)_c++并发控制新思路【实验性】的详细内容,更多请关注php中文网其它相关文章!

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号