Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用记忆屏障_C#_Multithreading_Lock Free_Memory Model - Fatal编程技术网

C# 使用记忆屏障

C# 使用记忆屏障,c#,multithreading,lock-free,memory-model,C#,Multithreading,Lock Free,Memory Model,在下面的代码示例中,是否需要FuncA中的内存屏障来确保读取最新的值 class Foo { DateTime m_bar; void FuncA() // invoked by thread X { Thread.MemoryBarrier(); // is required? Console.WriteLine(m_bar); } void FuncB() // invoked by thread Y { m_ba

在下面的代码示例中,是否需要FuncA中的内存屏障来确保读取最新的值

class Foo
{
   DateTime m_bar;

   void FuncA() // invoked by thread X
   {
      Thread.MemoryBarrier(); // is required?
      Console.WriteLine(m_bar);
   }

   void FuncB() // invoked by thread Y
   {
       m_bar = DateTime.Now;
   }       
}

编辑:如果不是,如何确保FuncA读取最新的值?我想确保最近的值实际上存储在处理器的缓存中[不使用锁]

对我来说似乎是一个很大的否定。MemoryBarrier仅同步实现它的线程内的内存访问

从MSDN:

执行当前线程的处理器不能以这样的方式对指令重新排序:在调用MemoryBarrier之前的内存访问在调用MemoryBarrier之后的内存访问之后执行


对我来说,这是一个很大的拒绝。MemoryBarrier仅同步实现它的线程内的内存访问

从MSDN:

执行当前线程的处理器不能以这样的方式对指令重新排序:在调用MemoryBarrier之前的内存访问在调用MemoryBarrier之后的内存访问之后执行


我建议您将Datetime存储为ticks of ticks,它的类型为long,即Int64,您可以轻松地将ticks从new Datetime ticks转换为ticks myDateTime.ticks。然后,您可以在快速非锁定操作中使用Interlocked.Read-to-Read值和Interlocked.Exchange-to-write值

我建议您将Datetime存储为ticks of ticks,它的类型为long,即Int64,您可以轻松地将ticks从new Datetime ticks转换为ticks myDateTime.ticks。然后,您可以在快速非锁定操作中使用Interlocked.Read-to-Read值和Interlocked.Exchange-to-write值

是的,需要内存屏障,以便获得最新的值

如果内存屏障不存在,则线程X可以从其自己的缓存线读取m_bar的值,而该值尚未写回主存,更改已被设置为线程Y的本地。您可以通过将变量声明为volatile来实现相同的效果:

volatile修饰符通常用于由多个线程访问而不使用lock语句序列化访问的字段。使用volatile修饰符可以确保一个线程检索另一个线程写入的最新值


关于这个问题的一个很好的条目可能最好是Joe Duffy的这一条:

是的,需要内存屏障,以便您可以获得最新的值

如果内存屏障不存在,则线程X可以从其自己的缓存线读取m_bar的值,而该值尚未写回主存,更改已被设置为线程Y的本地。您可以通过将变量声明为volatile来实现相同的效果:

volatile修饰符通常用于由多个线程访问而不使用lock语句序列化访问的字段。使用volatile修饰符可以确保一个线程检索另一个线程写入的最新值


关于这个问题的一个很好的条目可能是Joe Duffy的这一条最好的条目:

内存屏障的作用与wat锁定的作用是一样的,保证字段将得到它的 进入锁时内存中的最新值,并在退出锁前写入内存。 确保字段的值始终读取或写入内存,并且从不通过读取或写入进行优化 也可以通过使用volatile关键字来实现对cpu缓存的第一次访问。 除非基元整数类型和引用类型不能缓存在CPU寄存器ad中,否则DateTime
不需要也不能用volatile关键字声明。

内存屏障的作用与wat锁定的作用相同,保证字段将获得其 进入锁时内存中的最新值,并在退出锁前写入内存。 确保字段的值始终读取或写入内存,并且从不通过读取或写入进行优化 也可以通过使用volatile关键字来实现对cpu缓存的第一次访问。 除非基元整数类型和引用类型不能缓存在CPU寄存器ad中,否则DateTime
不需要也不能用volatile关键字声明。

这实际上无关紧要,因为在32位体系结构上,在这种情况下可以得到一个撕裂的读取。

这实际上无关紧要,因为在32位体系结构上,在这种情况下也可以得到撕裂的读取。

。。。听起来像是家庭作业其实不是,只是出于兴趣。你为什么要把尸体移走?如果你不再喜欢你的问题,请删除它,不要让它成为一个无用的空问题。不要删除它,因为有太多的答案/投票。不要关闭它,它太脏了,无法删除正文的内容,让它成为一个空问题。这个问题有点相关和有趣,就让它原样吧。没有人投反对票,我发现这是一个有趣的问题。而且。。。听起来像是家庭作业,其实不是,只是出于兴趣。你为什么去掉b
奥迪?如果你不再喜欢你的问题,请删除它,不要让它成为一个无用的空问题。不要删除它,因为有太多的答案/投票。不要关闭它,它太脏了,无法删除正文的内容,让它成为一个空问题。这个问题有点相关和有趣,就让它原样吧。没有人投反对票,事实上我发现这是一个有趣的问题。这是不使用同步块监视器的唯一方法。进入和退出,也称为lockfoo,因为联锁仅适用于长或整数。这里的一个示例:这是不使用同步块监视器的唯一方法。进入和退出,也称为lockfoo,因为Interlocated只适用于long或int。这里有一个例子:有趣的是,MemoryBarrier的描述在.NET 2.0和.NET 3.5 2.0=>中有所不同。实际上,为执行当前线程的处理器将缓存内存的内容刷新到主内存。3.5==>按如下方式同步内存访问:执行当前线程的处理器不能以这样的方式重新排列指令,即调用MemoryBarrier之前的内存访问在调用MemoryBarrier之后的内存访问之后执行。有趣的是,MemoryBarrier的描述在.NET 2.0和.NET 3.5 2.0中有所不同=>同步内存。实际上,为执行当前线程的处理器将缓存内存的内容刷新到主内存。3.5==>按如下方式同步内存访问:执行当前线程的处理器不能以这样的方式重新排序指令:在调用MemoryBarrier之前的内存访问在调用MemoryBarrier之后的内存访问之后执行。