std :: memory_order_seq_cst的工作方式 [英] How std::memory_order_seq_cst works

查看:428
本文介绍了std :: memory_order_seq_cst的工作方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从以下示例中获取了有关std :: memory_order_seq_cst的示例: http://en.cppreference.com/w/cpp/atomic/memory_order

I took the example about std::memory_order_seq_cst from: http://en.cppreference.com/w/cpp/atomic/memory_order

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

std::atomic<bool> x = {false};
std::atomic<bool> y = {false};
std::atomic<int> z = {0};

void write_x()
{
    x.store(true, std::memory_order_seq_cst);
}

void write_y()
{
    y.store(true, std::memory_order_seq_cst);
}

void read_x_then_y()
{
    while (!x.load(std::memory_order_seq_cst))
        ;
    if (y.load(std::memory_order_seq_cst)) {
        ++z;
    }
}

void read_y_then_x()
{
    while (!y.load(std::memory_order_seq_cst))
        ;
    if (x.load(std::memory_order_seq_cst)) {
        ++z;
    }
}

int main()
{
    std::thread a(write_x);
    std::thread b(write_y);
    std::thread c(read_x_then_y);
    std::thread d(read_y_then_x);
    a.join(); b.join(); c.join(); d.join();
    assert(z.load() != 0);  // will never happen
}

>获取/发布与顺序一致内存顺序.

我的问题是线程c和线程d怎么可能看到不同的东西?如果可能,为什么下面的这个简单示例始终得出z = 3?例如,线程b可能会说即使线程a已经完成,我也会看到0,所以z再次变为0 + 1"

My question is how it is possible that thread c and thread d see different things? If it is possible, why this simple example below always yields to z=3? For instance, thread b could say "okay I see 0 even though thread a is already done so z becomes 0+1 again"

#include <atomic>
#include <iostream>

std::atomic<int> z = {0};

void increment()
{
    z.fetch_add(1, std::memory_order_relaxed);
}
int main()
{
    std::thread a(increment);
    std::thread b(increment);
    std::thread c(increment);
    a.join(); b.join(); c.join();
    std::cout << z.load() << '\n';
}

推荐答案

因此,通过在注释中看到不同的内容,您表示线程C看到x == 1,y == 0,线程D看到x == 0和y == 1 .顺序一致可以做到这一点吗?

So by seeing different things in your comment you mean that Thread C see x==1,y==0 and Thread D see x==0 and y==1. Is that possible with sequential consistency?

让我们假设这个总顺序(修改是这些符号化内存状态之间的转换):

Let's suppose this total order (the modification is the transition between this symbolized memory states):

{x==0,y==0} : S0
{x==1,y==0} : S1
{x==1,y==1} : S2

当我们说"see"时,是指潜在线程执行负载.不能在一个线程中同时执行两个加载.那么,线程C怎么可能看到x == 1 然后看到y == 0而线程D看到了x == 0 = 然后看到了y == 1?线程C在内存处于状态S1时执行两次加载,线程D在状态S0看到x,然后在状态S2看到y.

When we say "see" we mean that a thread potentialy performs a load. Two loads can not be performed simultaneously in one thread. So how is it possible that thread C see x==1 then see y==0 and Thread D see x==0 then see y==1? Thread C performs the two loads while the memory is in the state S1, and Thread D see x at state S0, then see y at state S2.

在您的示例代码中,发生的情况是线程C加载x然后加载y,线程D重复加载y,直到它为true然后加载x.因此,在y == 1之后,可以保证x==1以此总顺序进行.

In your example code, what happens is that Thread C load x then load y, and Thread D load y repeatedly until it is true then load x. So after y==1, it is guarenteed that x==1 in this total order.

如Minee在其评论中所述,如果使用顺序一致性存储顺序来代替获取/释放存储顺序,则不会有什么期望:获取/释放语义并不意味着任何总排序,而且没有发生到x的商店和到y的商店之间的关系.因此,断言z.load()!=0可能会触发.

As said by Minee in its comment, nothing could be expected if in place of sequential consistency memory order were used acquire/release memory order: acquire/release semantic does not imply any total ordering,moreover there are no happens before relation between the store to x and the store to y. So the assertion z.load()!=0 could fire.

这篇关于std :: memory_order_seq_cst的工作方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆