gpt4 book ai didi

c# - 内存屏障是否保证在 C# 中重新读取?

转载 作者:太空狗 更新时间:2023-10-30 00:38:49 24 4
gpt4 key购买 nike

如果我们在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

我知道已经存在几个与 C# 中的“新鲜度”和 MemoryBarrier 相关的问题,例如 thisthis .然而,它们中的大多数都处理写-释放和读-获取模式。在这个问题中发布的代码非常具体地说明了是否保证在指令保持顺序的情况下读取可以查看写入。

最佳答案

不能保证看到两个线程都写入 1It only guarantees the order of read/write operations基于这个规则:

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.

所以这基本上意味着 thread A 的线程不会使用变量 b 的值读取 before 屏障的调用.但如果您的代码是这样的,它仍然会缓存该值:

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);
}

并行执行的竞争条件错误很难重现,所以我无法为您提供肯定会执行上述场景的代码,但我建议您使用 volatile keyword对于不同线程正在使用的变量,因为它完全按照您的意愿工作 - 让您重新阅读变量:

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# - 内存屏障是否保证在 C# 中重新读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38050681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com