atomic的使用例子

    const auto updateToMaxDepth = [](std::atomic<float>& d, const float depth) {
        float oldD = d.load();
        while (oldD < depth && !d.compare_exchange_weak(oldD, depth)) {
        }
    };

这段代码定义了一个名为 updateToMaxDepth 的 lambda 函数,其功能与之前的 updateDepth 函数类似。它的作用是确保原子变量 d 中存储的值始终是给定深度值 depth 和当前存储值之间的最大值。

代码逐行解释:

  1. Lambda 函数定义:

    const auto updateToMaxDepth = [](std::atomic<float>& d, const float depth) { ... };

    • const auto updateToMaxDepth:定义了一个常量的 auto 变量 updateToMaxDepth,它是一个 lambda 函数。
    • [](std::atomic<float>& d, const float depth):这个 lambda 函数接受两个参数:
      • std::atomic<float>& d:对一个原子 float 变量的引用,表示当前的深度值。
      • const float depth:一个浮点数,表示要尝试更新的深度值。
  2. 加载原子变量的当前值:

    float oldD = d.load();

    • d.load():从原子变量 d 中加载当前值,并将其赋值给局部变量 oldD
  3. While 循环:

    while (oldD < depth && !d.compare_exchange_weak(oldD, depth)) { }

    • 这个循环的作用是尝试将原子变量 d 的值更新为 depth,但只有当 depth 大于当前值 oldD 时才会进行更新。具体逻辑如下:
      1. oldD < depth:检查当前的深度值是否小于提供的深度值 depth
      2. !d.compare_exchange_weak(oldD, depth):尝试将 d 的值更新为 depth,前提是 d 的当前值仍然是 oldD。如果在此期间 d 的值被其他线程修改了,那么 compare_exchange_weak 会失败,并将 oldD 更新为 d 的新值。
    • 循环会持续进行,直到 d 成功更新为 depth 或者 d 的当前值不再小于 depth

代码的目的:

updateToMaxDepth 函数用于在多线程环境中安全地更新 d,以确保其始终保持为当前已知的最大深度值。通过使用原子操作,可以避免多个线程同时更新 d 时发生的数据竞争(data race),确保结果的正确性。

举例:

线程间无干扰

假设初始状态:
  • 初始情况下,d 的值为 5.0
  • 有三个线程 T1T2T3,它们分别尝试将 d 更新为不同的深度值:
    • T1 尝试更新 d7.0
    • T2 尝试更新 d6.0
    • T3 尝试更新 d8.0
线程执行过程:
1. 线程 T1 执行:
  • T1 加载 d 的当前值 5.0(即 oldD = 5.0)。
  • T1 检查 oldD < depth(即 5.0 < 7.0),条件为真。
  • T1 尝试使用 compare_exchange_weakd 更新为 7.0。由于 d 当前仍为 5.0,更新成功,d 变为 7.0
2. 线程 T2 执行:
  • T2 加载 d 的当前值 7.0(即 oldD = 7.0)。
  • T2 检查 oldD < depth(即 7.0 < 6.0),条件为假。
  • 因为条件不满足,T2 不进行更新操作,d 的值保持为 7.0
3. 线程 T3 执行:
  • T3 加载 d 的当前值 7.0(即 oldD = 7.0)。
  • T3 检查 oldD < depth(即 7.0 < 8.0),条件为真。
  • T3 尝试使用 compare_exchange_weakd 更新为 8.0。由于 d 当前仍为 7.0,更新成功,d 变为 8.0

线程相互干扰case

假设初始状态:
  • 初始情况下,d 的值为 5.0
  • 有三个线程 T1T2T3,它们分别尝试将 d 更新为不同的深度值:
    • T1 尝试更新 d7.0
    • T2 尝试更新 d6.0
    • T3 尝试更新 d8.0
线程执行过程:
1. 线程 T1 执行:
  • T1 加载 d 的当前值 5.0(即 oldD = 5.0)。
  • T1 检查 oldD < depth(即 5.0 < 7.0),条件为真。
  • 此时线程T3执行结束了
  • T1 尝试使用 compare_exchange_weakd 更新为 7.0由于 d 当前仍为 8.0,更新失败,oldD 变为 8.0
  • 此时T1 检查 oldD < depth(即 8.0 < 7.0),条件为假。退出循环。
2. 线程 T2 执行:
  • T2 加载 d 的当前值 8.0(即 oldD = 8.0)。
  • T2 检查 oldD < depth(即 8.0 < 6.0),条件为假。
  • 因为条件不满足,T2 不进行更新操作,d 的值保持为 8.0
3. 线程 T3 执行:
  • T3 加载 d 的当前值 5.0(即 oldD = 5.0)。
  • T3 检查 oldD < depth(即 5.0 < 8.0),条件为真。
  • T3 尝试使用 compare_exchange_weakd 更新为 8.0。由于 d 当前仍为 5.0,更新成功,d 变为 8.0
  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值