- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
为了实现多线程应用程序的无锁代码,我使用了volatile
变量,理论上:volatile
关键字只是用来确保所有线程都能看到volatile变量的最新值;因此,如果线程 A
更新了变量值,而线程 B
在更新发生后立即读取该变量,它将看到最近从线程 A 写入的最新值。正如我在一本C# 4.0 in a Nutshell 书中读到的那样这是不正确因为
applying volatile doesn’t prevent a write followed by a read from being swapped.
这个问题是否可以通过在每次获取 volatile
变量之前放置 Thread.MemoryBarrier()
来解决,例如:
private volatile bool _foo = false;
private void A()
{
//…
Thread.MemoryBarrier();
if (_foo)
{
//do somthing
}
}
private void B()
{
//…
_foo = true;
//…
}
如果这解决了问题;考虑我们有一个 while 循环,它在其条件之一时依赖于该值;在 while 循环之前放置 Thread.MemoryBarrier()
是解决问题的正确方法吗?示例:
private void A()
{
Thread.MemoryBarrier();
while (_someOtherConditions && _foo)
{
// do somthing.
}
}
更准确地说,我希望 _foo
变量在任何线程随时请求它时提供它的最新值;因此,如果在调用变量之前插入 Thread.MemoryBarrier()
可以解决问题,那么我可以使用 Foo
属性而不是 _foo
并执行 Thread.MemoryBarrier()
在该属性的获取中 喜欢:
Foo
{
get
{
Thread.MemoryBarrier();
return _foo;
}
set
{
_foo = value;
}
}
最佳答案
“C# In a Nutshell”是正确的,但它的陈述没有实际意义。为什么?
让我们澄清一下。拿你的原始代码:
private void A()
{
//…
if (_foo)
{
//do something
}
}
如果线程调度程序已经检查了 _foo
变量,但它在 //do something
注释之前被挂起,会发生什么情况?那么,此时您的其他线程可能会更改 _foo
的值,这意味着您所有的 volatiles 和 Thread.MemoryBarriers 都没有意义!!!如果在 _foo
的值为 false 时绝对必须避免 do_something
,那么您别无选择,只能使用锁。
但是,如果 do something
可以在 _foo
突然变为 false 时执行,那么这意味着 volatile 关键字足以满足您的需求。
需要明确的是:所有告诉您使用内存屏障的响应者都是不正确的,或者提供了过大的杀伤力。
关于c# - C# 中的 Volatile 和 Thread.MemoryBarrier,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4269498/
VB.Net 没有等效的 C# volatile 关键字,因此您必须手动实现 volatile,这通常通过在读取之前和写入之后调用 Thread.MemoryBarrier() 来完成。所以这样的事情
using System; using System.Threading; using System.Threading.Tasks; class Program { static void
我修改了 Non-Blocking Synchronization 上给出的程序如下: class DemoProg { int _answer; bool _complete;
如果我理解正确,在 C# 中,一个 lock block 保证对一组指令的独占访问,但它也保证从内存中读取的任何内容都反射(reflect)了任何 CPU 缓存中该内存的最新版本.我们将 lock b
我需要一种可靠的方法来获得系统正常运行时间,并最终使用了如下方法。添加了一些评论以帮助人们阅读它。我不能使用任务,因为它必须在 .NET 3.5 应用程序上运行。 // This is a struc
由于似乎上下文切换可能发生在指令执行的任何时刻,所以我现在想知道为什么代码“部分有问题”(那两条指令)有意义,如果上下文切换可以在任何指令之间发生并且我们可能在不同的CPU上第二条指令的核心。 voi
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Why we need Thread.MemoryBarrier()? 摘自 O'Reilly 的 C# i
在 Java 中,我如何显式触发一个完整的内存栅栏/屏障,等于调用 System.Threading.Thread.MemoryBarrier(); 在 C# 中? 我知道,自从 Java 5 读取和
对于以下场景,使用MemoryBarrier在线程安全性、结果和性能方面是否有任何差异 private SomeType field; public SomeType Property { g
在这本线程在线书籍中:http://www.albahari.com/threading/part4.aspx 有一个 Thread.MemoryBarrier() 的例子 class Foo
这个网站的新手,所以如果我没有以可接受的方式发帖请告诉我。 我经常按照下面的示例编写代码(为清楚起见,省略了 Dispose 之类的内容。)。我的问题是,是否需要如图所示的 volatile ?或者
在“C# 4 in a Nutshell”中,作者展示了这个类有时可以在没有 MemoryBarrier 的情况下写入 0,尽管我无法在我的 Core2Duo 中重现: public class Fo
在 .NET 中 lock关键字是 Monitor.Enter 周围的语法糖和 Monitor.Exit ,所以你可以说这段代码 lock(locker) { // Do something }
下面的 GLSL 计算着色器简单地复制了 inImage至 outImage .它源自更复杂的后处理过程。 在main()的前几行,单个线程将 64 个像素的数据加载到共享数组中。然后,在同步之后,6
根据Web,我找到了如下代码,相当于C# Volatile for VB.NET。 代码引用:How do I specify the equivalent of volatile in VB.net
只是在业余时间玩并发性,并想尝试在不使用读取器端锁定的情况下防止撕裂读取,以便并发读取器不会相互干扰。 这个想法是通过锁序列化写入,但在读取端仅使用内存屏障。这是一个可重用的抽象,它封装了我提出的方法
通过浏览 MEF 源代码,我找到了这篇文章。有人可以解释为什么锁内需要 MemoryBarrier 吗? 整个方法是: public void SatisfyImportsOnce(Composabl
假设我有一个字段控制某个循环的执行: private static bool shouldRun = true; 我有一个正在运行的线程,其代码如下: while(shouldRun) { /
在 msdn 上 http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208(v=vs.85).aspx , MemoryBarr
如果我正确理解 volatile 和 MemoryBarrier 的含义,那么下面的程序将永远无法显示任何结果。 每次我运行它时,它都会捕获写入操作的重新排序。我在 Debug 或 Release 中
我是一名优秀的程序员,十分优秀!