相关疑难解决方法(0)

我们需要在多线程代码中读取.NET Int32时锁定它?

我正在阅读以下文章:http: //msdn.microsoft.com/en-us/magazine/cc817398.aspx "解决你的多线程代码中的11个可能的问题"作者:Joe Duffy

它提出了一个问题:"我们需要在用多线程代码读取它时锁定.NET Int32吗?"

据我所知,如果它是32位SO中的Int64,它可能会撕裂,正如文章中所解释的那样.但对于Int32,我想到了以下情况:

class Test
{
  private int example = 0;
  private Object thisLock = new Object();

  public void Add(int another)
  {
    lock(thisLock)
    {
      example += another;
    }
  }

  public int Read()
  {
     return example;
  }
}
Run Code Online (Sandbox Code Playgroud)

我没有看到在Read方法中包含锁的原因.你呢?

更新基于答案(由Jon Skeet和ctacke提供)我理解上面的代码仍然容易受到多处理器缓存的影响(每个处理器都有自己的缓存,与其他处理器不同步).所有这三个修改都解决了这个问题:

  1. 添加"int example"的"volatile"属性
  2. 插入Thread.MemoryBarrier(); 在实际读取"int example"之前
  3. 在"lock(thisLock)"中读取"int example"

而且我也认为"易变"是最优雅的解决方案.

.net c# multithreading locking

14
推荐指数
2
解决办法
7061
查看次数

何时在.NET中使用lock vs MemoryBarrier

在.NET中的lock关键字是语法糖各地Monitor.EnterMonitor.Exit,所以你可以说,这段代码

lock(locker)
{
  // Do something
}
Run Code Online (Sandbox Code Playgroud)

是相同的

Monitor.Enter(locker);
try
{
  // Do Something
}
finally
{
  Monitor.Exit(locker);
}
Run Code Online (Sandbox Code Playgroud)

但是,.NET框架还包括MemoryBarrier以类似方式工作的类

Thread.MemoryBarrier();
//Do something
Thread.MemoryBarrier();
Run Code Online (Sandbox Code Playgroud)

我很困惑,当我想用Thread.MemoryBarrierlock/ Monitor版本?我更加困惑的是线程教程,它表明它们的功能相同.

据我所知,可见的区别是不需要锁定对象,我想使用Monitor你可以跨线程做一些事情MemoryBarrier在一个线程上.

我的直觉告诉我,另一个关键的区别是MemoryBarrier仅变量而不是方法.

最后这与现有问题无关何时在线程安全锁定代码中使用'volatile'或'Thread.MemoryBarrier()'?(C#),因为它专注于volatile我理解其使用的关键字.

.net multithreading locking monitor memory-barriers

12
推荐指数
1
解决办法
4214
查看次数

C#中的Volatile和Thread.MemoryBarrier

为了实现多线程应用程序的无锁代码,我使用了volatile变量, 理论上:该volatile关键字仅用于确保所有线程都能看到volatile变量的最新值; 因此,如果线程A更新变量值并且线程B在该更新发生之后读取该变量,它将看到最近从线程A写入的最新值.正如我在Nutshell书中的C#4.0中读到的那样,这是不正确的,因为

应用volatile不会阻止写入后读取交换.

可以通过Thread.MemoryBarrier()在每次获取volatile变量之前放置来解决这个问题:

private volatile bool _foo = false;

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

private void B()
{
    //…
    _foo = true;
    //…
}
Run Code Online (Sandbox Code Playgroud)

如果这解决了问题; 考虑我们有一个while循环,它依赖于其中一个条件的值; Thread.MemoryBarrier()在while循环之前放置是解决问题的正确方法吗?例:

private void A()
{
    Thread.MemoryBarrier();
    while (_someOtherConditions && _foo)
    {
        // do somthing.
    }
}
Run Code Online (Sandbox Code Playgroud)

为了更准确,我希望_foo变量在任何时候任何线程要求它时给出最新的值; 因此,如果Thread.MemoryBarrier()在调用变量之前插入修复问题,那么我可以使用 …

c# memory-management volatile nonblocking memory-barriers

9
推荐指数
2
解决办法
4056
查看次数

多线程线程安全读/写锁定的最佳C#解决方案?

static在C#中对多线程环境中的成员执行锁定读/写访问的最安全(和最短)方法是什么?

是否可以在类级别上执行线程安全锁定和解锁(因此,每次需要静态成员访问时,我都不会继续重复锁定/解锁代码)?

编辑:示例代码会很棒:)

编辑:我应该使用volatile关键字或Thread.MemoryBarrier()来避免多处理器缓存还是不必要?根据Jon Skeet的说法,只有那些会让其他处理器看到变化吗?(另被问及这在这里).

.net c# multithreading

4
推荐指数
2
解决办法
2万
查看次数