从外部函数

时间:2017-03-07 09:59:31

标签: c# multithreading thread-safety

我正在尝试追踪我认为可能与多线程应用程序相关的错误。我简化了下面的代码:

class Outer {
  private static int count;

  //this function is called from multiple threads in quick succession
  public void DoFoo() {
    Inner.Increment(ref count);
  }
}

class Inner {
  private readonly static object mLock = new object();
  public static string Increment(ref count) {
    lock (mLock) (
      if (count > 1000)
        count = 0;
      count++;
    }
    return count.ToString();
  }
}

锁定能否保证以这种方式传递的变量的安全性?是否有任何复制计数似乎不明显,可能会打破内存安全?我以为它可能会返回一个新的int并在方法结束时进行赋值。除此之外,我的理解是锁定部分将处理任何缓存问题。

引起我们注意的错误似乎是其中一个线程有一个陈旧版本的计数。

1 个答案:

答案 0 :(得分:2)

这里的问题是,当某个其他线程为== 0时,可以直接读取>>> a = { "system1": "Service 1", "System2": "Service2" } >>> b = json.loads(a) >>> b {u'system1': u'Service 1', u'System2': u'Service2'} ,因为您可以在没有获得锁定的情况下访问b['system1'] (通常在您的代码中写入,{ {1}}只能在第一次调用Outer.count之前为0,从那时起它只能有1到1001之间的值。

无锁可以这样做:

Outer.count

我计算count值并使用它(通过Inner.Increment)只有class Inner { public static string Increment(ref int count) { while (true) { int original = count; int next = original; if (next > 1000) { next = 0; } next++; if (Interlocked.CompareExchange(ref count, next, original) == original) { return next.ToString(); } } } } 在此期间未发生变化。