挥发性和Thread.MemoryBarrier在C# [英] Volatile and Thread.MemoryBarrier in C#

查看:130
本文介绍了挥发性和Thread.MemoryBarrier在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要实施的锁定免费代码作为多线程应用程序,我用挥发性变量,
理论上:在挥发性关键字只是用来确保所有线程看到volatile变量的最新值;因此,如果线程 A 更新变量值和螺纹 B 读该变量只是之后更新发生会看到大多数从线程A
最近写正如我在 C#4.0果壳中的的书,
不正确,因为


应用挥发性并不妨碍写操作后紧跟读被调换了。




难道这个问题正在通过把解决 Thread.MemoryBarrier()每前获得挥发性像变量:

 私人挥发性布尔_foo = FALSE; 

私人无效A()
{
// ...
Thread.MemoryBarrier();
如果(_foo)
{
//做财产以后
}
}

私人无效B()
$ { b $ b // ...
_foo = TRUE;
// ...
}

和是否能解决这个问题;考虑到我们有一个while循环依赖于它的条件之一值;是把 Thread.MemoryBarrier()前while循环是解决这一问题的正确方法?例如:

 私人无效A()
{
Thread.MemoryBarrier();
,而(_someOtherConditions&安培;&安培; _foo)
{
//做财产以后。
}
}

要更精确我想要的 _foo 变量给当任何线程在任何时候要求它最新鲜的价值;因此,如果插入 Thread.MemoryBarrier()之前调用变量修复了问题,那么我可以使用属性,而不是 _foo ,并做了 Thread.MemoryBarrier()该属性一样的get内:

 
{
得到
{
Thread.MemoryBarrier();
返回_foo;
}

{
_foo =价值;
}
}


解决方案

的C#果壳中的是正确的,但它的说法是没有实际意义。为什么?




  • A'写'后'读',withot'挥发',保证在节目顺序发生不管怎样的如果它影响逻辑在一个线程中

  • 在多线程程序中的读之前,'写'是的毫无意义的后顾之忧关于你的榜样。



让我们澄清一下。把你的原代码:

 私人无效A()
{
// ...
如果(_foo)
{
//做些什么
}
}

如果线程调度器已经检查了 _foo 变量,但它只是取暂停前会发生什么//做一些事情对此有何评论?那么,在这一点上你的其他线程可能会改变 _foo 的值,这意味着所有的挥发物和Thread.MemoryBarriers计数什么!如果是完全有必要的 do_something 避免如果 _foo 的值是假的,那么你有没有选择,只能使用锁。



但是,如果它是确定的做点什么被执行时,突然 _foo 为假,那么就意味着volatile关键字是足以满足您的需求更多。



需要明确的是:所有的谁告诉你使用一个内存屏障反应是不正确的或正在提供矫枉过正。


To implement a lock free code for multithreading application I used volatile variables, Theoretically: The volatile keyword is simply used to make sure that all threads see the most updated value of a volatile variable; so if thread A updates the variable value and thread B read that variable just after that update is happened it will see the most updated value that written recently from thread A. As I read in a C# 4.0 in a Nutshell book that this is incorrect because

applying volatile doesn’t prevent a write followed by a read from being swapped.

Could this problem being solved by putting Thread.MemoryBarrier() before every get of the volatile variable like:

private volatile bool _foo = false;

private void A()
{
    //…
    Thread.MemoryBarrier();
    if (_foo)
    {
        //do somthing
    }
}

private void B()
{
    //…
    _foo = true;
    //…
}

And if this solves the problem; consider we have a while loop that depend on that value at one of its conditions; is putting Thread.MemoryBarrier() before the while loop is a correct way to fix the issue? example:

private void A()
{
    Thread.MemoryBarrier();
    while (_someOtherConditions && _foo)
    {
        // do somthing.
    }
}

To be more accurate I want the _foo variable to give its most fresh value when any thread asking for it at any time; so if inserting Thread.MemoryBarrier() before calling the variable fixes the issue then could I use Foo property instead of _foo and do a Thread.MemoryBarrier() within the get of that property Like:

Foo
{
    get 
    {
        Thread.MemoryBarrier();
        return _foo;
    }
    set
    {
        _foo = value;
    }
}

解决方案

The "C# In a Nutshell" is correct, but its statement is moot. Why?

  • A 'write' followed by a 'read', withot 'volatile', is guaranteed to occur in program-order anyway if it effects logic within a single thread
  • The 'write' before a 'read' in a multi-threaded program is utterly pointless to worry about in your example.

Let's clarify. Take your original code:

private void A() 
{ 
    //… 
    if (_foo) 
    { 
        //do something 
    } 
}

What happens if the thread scheduler has already checked the _foo variable, but it gets suspended just before the //do something comment? Well, at that point your other thread could change the value of _foo, which means that all your volatiles and Thread.MemoryBarriers counted for nothing!!! If it is absolutely essential that the do_something be avoided if the value of _foo is false, then you have no choice but to use a lock.

However, if it is ok for the do something to be executing when suddenly _foo becomes false, then it means the volatile keyword was more than enough for your needs.

To be clear: all the responders who are telling you to use a memory barrier are incorrect or are providing overkill.

这篇关于挥发性和Thread.MemoryBarrier在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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