jjzjj

Volatile

全部标签

c# - 为什么(或不是)在构造函数中设置字段是线程安全的?

假设您有一个像这样的简单类:classMyClass{privatereadonlyinta;privateintb;publicMyClass(inta,intb){this.a=a;this.b=b;}publicintA{get{returna;}}publicintB{get{returnb;}}}我可以以多线程方式使用这个类:MyClassvalue=null;Task.Run(()=>{while(true){value=newMyClass(1,1);Thread.Sleep(10);}});while(true){MyClassresult=value;if(resul

C# 可变数组项?

我需要一个包含可变项的数组,但找不到实现该操作的方法。privatevolatileT[]_arr;这意味着_arr引用是可变的,但是它不保证_arr对象本身内部的项目的任何内容。有什么方法可以将_arr的项目标记为易变的吗?谢谢。编辑:根据binarycoder的答案构建了以下代码。这段代码使用起来线程安全吗?publicclassVolatileArray{privateT[]_arr;publicVolatileArray(intlength){_arr=newT[length];}publicVolatileArray(T[]arr){_arr=arr;}publicTthis

c# - 为什么 volatile 和 MemoryBarrier 不阻止操作重新排序?

如果我正确理解volatile和MemoryBarrier的含义,那么下面的程序将永远无法显示任何结果。每次我运行它时,它都会捕获写入操作的重新排序。我在Debug或Release中运行它并不重要。将它作为32位或64位应用程序运行也没有关系。为什么会这样?usingSystem;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceFlipFlop{classProgram{//Declaringthesevariablesasvolatileshouldinstructcompilerto//flushallcache

c# - .NET JIT 编译器可变优化

https://msdn.microsoft.com/en-us/magazine/jj883956.aspxConsiderthepollinglooppattern:privatebool_flag=true;publicvoidRun(){//Set_flagtofalseonanotherthreadnewThread(()=>{_flag=false;}).Start();//Pollthe_flagfielduntilitissettofalsewhile(_flag);//Theloopmightneverterminate!}Inthiscase,the.NET4.5J

c# - 在哪里放置栅栏/内存屏障以保证新的读取/提交的写入?

像许多其他人一样,我一直对不稳定的读/写和栅栏感到困惑。所以现在我正试图完全理解它们的作用。因此,volatile读取应该(1)表现出获取语义(2)保证读取的值是新鲜的,即它不是缓存值。让我们关注(2)。现在,I'veread也就是说,如果你想执行volatile读取,你应该在读取之后引入一个获取栅栏(或一个完整的栅栏),就像这样:intlocal=shared;Thread.MemoryBarrier();这究竟是如何防止读取操作使用以前缓存的值的?根据栅栏的定义(不允许读取/存储在栅栏上方/下方移动),我会在读取之前插入栅栏,防止读取越过栅栏并被移动及时向后(也就是被缓存)。防止读

c# - 半栅栏和全栅栏?

我一直在阅读Fullfences可以防止任何类型的指令在该围栏周围重新排序或缓存(通过memoryBarrier)然后,我阅读了有关生成“半栅栏”的volatile的信息:Thevolatilekeywordinstructsthecompilertogenerateanacquire-fenceoneveryreadfromthatfield,andarelease-fenceoneverywritetothatfield.获得栅栏Anacquire-fencepreventsotherreads/writesfrombeingmovedbeforethefence;释放栅栏Arel

C# - 真的需要 "volatile"作为关键字吗?

随着我越来越深入地了解volatile关键字的含义,我一直对自己说“这是实现的方式,这不应该是一种高级编程语言”。我的意思是,CPU缓存数据这一事实对于JIT编译器来说应该很有趣,而不是C#程序员。一个重要的替代方案可能是属性(例如,VolatileAttribute)。你怎么看? 最佳答案 我觉得你走偏了。所有关于缓存等技术的东西都是试图用低层次的术语来解释它的一部分。volatile的功能描述是“我可能会被共享”。鉴于默认情况下线程之间无法共享任何内容,这并不奇怪。而且我认为基本足以保证在属性上使用关键字,但我认为它在很大程度上

C#变量新鲜度

假设我在一个类中有一个成员变量(具有原子读/写数据类型):boolm_Done=false;然后我创建一个任务将其设置为true:Task.Run(()=>m_Done=true);我不在乎什么时候m_Done会被设置为true。我的问题是C#语言规范和任务并行库是否可以保证如果我从不同的线程访问它,最终m_Done将为真?示例:if(m_Done){//Dosomething}我知道使用锁会引入必要的内存屏障,并且m_Done稍后会显示为true。我也可以在设置变量时使用Volatile.Write,在设置变量时使用Volatile.Read阅读它。我看到很多代码都是这样写的(没有锁

c# - volatile 变量有用吗?如果是,那么什么时候?

回复thisquestion让我想到了一些对我来说仍然不清楚的事情。让我们首先假设我们从thispost读取所有内容和thispost.[开始编辑]也许它不是那么明显(意大利幽默?!)但标题非常具有挑衅性:当然应该有一个原因,如果volatile已包含在C#中,我只是无法理解确切的内容。[结束编辑]简而言之,我们知道我们有三个工具可以在线程之间共享变量:lock因为这将阻止指令重新排序。volatile因为会强制CPU始终从内存中读取值(然后不同的CPU/内核不会缓存它,也不会看到旧值)。互锁操作(Increment/Decrement和CompareExchange)因为它们将在单个

c# - 流行的 "volatile polled flag"模式坏了吗?

假设我想使用一个bool状态标志来实现线程间的协作取消。(我意识到应该最好使用CancellationTokenSource代替;这不是这个问题的重点。)privatevolatilebool_stopping;publicvoidStart(){varthread=newThread(()=>{while(!_stopping){//Docomputationlastingaround10seconds.}});thread.Start();}publicvoidStop(){_stopping=true;}问题:如果我在另一个线程上在0秒调用Start()并在3秒调用Stop(),