【问题标题】:Acquire/Release Memory Ordering获取/释放内存排序
【发布时间】:2014-01-22 01:51:28
【问题描述】:

在示例中:

#include <thread>
#include <atomic>
#include <cassert>
#include <vector>

std::vector<int> data;
std::atomic<int> flag = ATOMIC_VAR_INIT(0);

void thread_1()
{
    data.push_back(42);
    flag.store(1, std::memory_order_release);
}

void thread_2()
{
    int expected=1;
    while (!flag.compare_exchange_strong(expected, 2, std::memory_order_acq_rel)) {
        expected = 1;
    }
}

void thread_3()
{
    while (flag.load(std::memory_order_acquire) < 2)
        ;
    assert(data.at(0) == 42); // will never fire
}

int main()
{
    std::thread a(thread_1);
    std::thread b(thread_2);
    std::thread c(thread_3);
    a.join(); b.join(); c.join();
}

1- 如果我将 thread_2 中的 std::memory_order_acq_rel 替换为 std::memory_order_acquire,我还能保证 thread_3 中的断言永远不会触发吗?

2 - std::memory_order_release 是否可以使用 std::memory_order_acquire 与 2 个线程同步(如果 2 个线程正在使用获取语义监视同一个标志)?

【问题讨论】:

  • 仅供参考,ATOMIC_VAR_INIT(foo) 用于 C 兼容性,std::atomic&lt;T&gt; flag{foo}; 具有完全相同的效果。

标签: c++ multithreading c++11 thread-safety


【解决方案1】:
  1. 您在线程 2 中没有可同步的内容,因此 std::memory_order_relaxed 内存排序在这里更合理。

  2. 变量x 的std::memory_order_release 标记存储与变量x 的std::memory_order_acquire 标记加载同步,即使是初始存储之后也是@987654323 上的原子读取-修改-写入操作序列@

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多