做内存屏障保证在C#中的新鲜读? [英] Do memory barriers guarantee a fresh read in C#?

查看:237
本文介绍了做内存屏障保证在C#中的新鲜读?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们在C#下面的代码:

If we have the following code in C#:

int a = 0;
int b = 0;

void A() // runs in thread A
{
    a = 1;
    Thread.MemoryBarrier();
    Console.WriteLine(b);
}

void B() // runs in thread B
{
    b = 1;
    Thread.MemoryBarrier();
    Console.WriteLine(a);
}



MemoryBarriers 制作确保写指令发生读取之前。然而,它保证一个线程的写被另一线程所读取见过?换句话说,它是保证至少有一个线程打印 1 或两个线程可以打印 0

The MemoryBarriers make sure that the write instruction takes place before the read. However, is it guaranteed that the write of one thread is seen by the read on the other thread? In other words, is it guaranteed that at least one thread prints 1 or both thread could print 0?

我知道已经存在几个问题是相关的新鲜和内存屏障在C#中,像<一个HREF =htt​​p://stackoverflow.com/questions/21652938/where-to-places-fences-memory-barriers-to-guarantee-a-fresh-read-committed-write/25110639?noredirect=1#comment63509441_25110639>这和这个。然而,大多数人处理写入释放和读收购模式。张贴在这个问题的代码,是非常具体的写入是否是保证由读上的事实的指示被保存在顺序顶部观察

I know that several questions exist already that are relevant to "freshness" and MemoryBarrier in C#, like this and this. However, most of them deal with the write-release and read-acquire pattern. The code posted in this question, is very specific to whether a write is guaranteed to be viewed by a read on top of the fact that the instructions are kept in order.

推荐答案

没有,没有。 它仅仅保证读/写操作基于这样的规则:

No, it does not. It only guarantees the order of read/write operations based on this rule:

执行当前线程以这样的方式不能重新排序指令的存储器存取的处理器的之前的呼叫内存屏障执行内存访问后的跟着叫内存屏障

The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier execute after memory accesses that follow the call to MemoryBarrier.

因此,这基本上意味着该线程的线程A 止跌 T选用一个值屏障的调用之前变量 b 。但它仍然缓存值,如果你的代码是这样的:

So this basically means that the thread for a thread A wouldn't use a value for the variable b read before the barrier's call. But it still cache the value if your code is something like this:

void A() // runs in thread A
{
    a = 1;
    Thread.MemoryBarrier();
    // b may be cached here
    // some work here
    // b is changed by other thread
    // old value of b is being written
    Console.WriteLine(b);
}



在竞争条件错误的并行执行是很难复制,所以我不能提供你肯定会做上述方案中的代码,但我建议你使用的 的变量挥发性关键字正在使用不同的线程,它的工作原理完全一样,你想要的 - 给你一个变量新读:

The race-condition bugs for a the parallel execution is very hard to reproduce, so I can't provide you a code that will definitely do the scenario above, but I suggest you to use the volatile keyword for the variables being used by different threads, as it works exactly as you want - gives you a fresh read for a variable:

volatile int a = 0;
volatile int b = 0;

void A() // runs in thread A
{
    a = 1;
    Thread.MemoryBarrier();
    Console.WriteLine(b);
}

void B() // runs in thread B
{
    b = 1;
    Thread.MemoryBarrier();
    Console.WriteLine(a);
}

这篇关于做内存屏障保证在C#中的新鲜读?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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