KENSCANF 2023-10-13 16:26 采纳率: 50%
浏览 8

c++17多线程原子操作 获取释放操作

img


图一

img


图二
为什么代码最后会触发断言z会为0?

在图二read_x_then_y()中,x.load为true.那么write_x()已经经缓存后并写入值true.此时read_x_then_y中,y.load()为false.是不是说明在y还没被write_y()缓存并写入true之前,x已经为true.那read_y_then_x()为什么x.load会为false?

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-13 21:32
    关注

    【以下回答由 GPT 生成】

    您好,

    根据您的描述,您遇到的问题是在使用C++17多线程原子操作时,使用了获取和释放操作,但是最终却触发了断言,导致 z 的值为 0。您想了解为什么在 read_y_then_x() 中的 x.load() 结果为 false。

    根据您提供的代码和问题描述,可以看出您的代码中存在数据竞争的问题。具体来说,您在 read_x_then_y()read_y_then_x() 中分别使用了 x 和 y 的加载操作,但是在另外两个线程(图中的 write_x()write_y())中也使用了相同的 x 和 y 的存储操作。这样做可能会导致读取到的值不一致,从而对断言进行触发。

    为了解决这个问题,您可以使用互斥量(mutex)或者原子操作进行同步,以确保线程之间的操作正确进行。下面是一种可能的解决方案:

    #include <iostream>
    #include <atomic>
    #include <thread>
    
    std::atomic_bool x(false);
    std::atomic_bool y(false);
    std::atomic_int z(0);
    
    void write_x_then_y() {
        x.store(true, std::memory_order_relaxed);
        std::atomic_thread_fence(std::memory_order_release);
        y.store(true, std::memory_order_relaxed);
    }
    
    void read_x_then_y() {
        while (!x.load(std::memory_order_relaxed));
        std::atomic_thread_fence(std::memory_order_acquire);
        if (y.load(std::memory_order_relaxed)) {
            ++z;
        }
    }
    
    void read_y_then_x() {
        while (!y.load(std::memory_order_relaxed));
        std::atomic_thread_fence(std::memory_order_acquire);
        if (x.load(std::memory_order_relaxed)) {
            ++z;
        }
    }
    
    int main() {
        std::thread t1(write_x_then_y);
        std::thread t2(read_x_then_y);
        std::thread t3(read_y_then_x);
    
        t1.join();
        t2.join();
        t3.join();
    
        assert(z.load() != 0);
        std::cout << "z = " << z.load() << std::endl;
    
        return 0;
    }
    

    在上述代码中,我们使用了 std::atomic_thread_fence() 函数以及 memory_order_acquirememory_order_release 内存序来保证对于 xy 的加载和存储操作进行正确排序。此外,我们还使用了一个互斥量来确保对 z 的操作是原子的。

    请注意,上述代码只是一种可能的解决方案,具体的实现可能因实际情况而异。如果问题依然存在或者您有其他疑问,请不要犹豫,随时向我提问。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月13日

悬赏问题

  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)