C++ std::atomic - 不可能基于共享原子变量同步 2 个线程

标签 c++ multithreading c++11 concurrency atomic

在我的程序中,2 个线程以矛盾(用于测试)的方式对一个简单数组进行排序。唯一的想法是防止两个线程同时使用 std::atomic 对数组进行排序。预期的结果是数组将根据“赢家线程”进行降序或升序排序。 我知道这可以很容易地用互斥量解决,但我只是在这里尝试了解 std::atomic 的好处。我的程序在所有执行案例中有 10% 失败:失败是两种情况交织在一起时...在此先感谢您的任何突出显示...

    std::array<int, 5> my_array{ 1, 4, 3, 2, 5 };
    std::atomic< std::array<int, 5>* > my_array_{ &my_array };

    std::thread my_thread(
        [&my_array_]() {
            std::array<int, 5>* my_array = nullptr;
            do { my_array = my_array_.load(std::memory_order_acquire); } while (my_array == nullptr);
            my_array_.store(nullptr, std::memory_order_release);

            std::sort(my_array->begin(), my_array->end(),
                [](const int a, const  int b) {
                    // std::cout << "\tascending a: " << a << " b: " << b << std::endl;
                    return a > b;
                });
            my_array_.store(my_array, std::memory_order_release);
        });

    std::thread my_thread_(
        [&my_array_]() {
            std::array<int, 5>* my_array = nullptr;
            do { my_array = my_array_.load(std::memory_order_acquire); } while (my_array == nullptr);
            my_array_.store(nullptr, std::memory_order_release);

            std::sort(my_array->begin(), my_array->end(),
                [](const int a, const int b) {
                    // std::cout << "\tdescending a: " << a << " b: " << b << std::endl;
                    return a < b;
                });
            my_array_.store(my_array, std::memory_order_release);
        });

    my_thread_.join();
    my_thread.join();

    for (const int i : my_array)
        std::cout << "\t" << i;

最佳答案

如果您想使用my_array_ 原子变量来指示某个线程是否已声明它,那么您可以简单地调用

auto local_array=my_array_.exchange(nullptr)

来自您的线程。如果这是第一个进行交换的线程,local_array 将因此成为指向 my_array 的指针,如果另一个线程首先到达那里,则 nullptr

就目前而言,通过简单的加载和存储,然后两个线程都可以读取 my_array_ 指针并看到它不是 nullptr,然后都可以存储 nullptr 在里面,并且都认为他们先到达那里。

此外:使用 my_array 作为全局名称, 本地指针的名称会造成混淆。

关于C++ std::atomic - 不可能基于共享原子变量同步 2 个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59047226/

相关文章:

java - 如何在 Netty channel 处理程序中安全地执行阻塞操作?

c++ - Boost asio 用于多个异步网络客户端操作

c++ - pthread_cond_wait() 之前的检查标志

c++ - 使用 libpq 组织 PostgreSQL 数据库连接参数?

c++ - Qt 5.1 for OSX 安装仅包含 clang_64 目录,如何使用 macports gcc 进行编译?

c++ - 使用多个命名空间

c++ - 在模板基类列表中使用类局部类型别名

c++ - perf 输出中的奇怪字符...

c++ - 包含派生对象的 QPointer 不会与基类匹配

c++ - 优化 std::deque 中的搜索