【问题标题】:Local volatile variable in C#C#中的局部易失变量
【发布时间】:2012-05-26 23:14:49
【问题描述】:

在我的 C# 程序中,我有方法代码:

Object model;
int score;
for()
{
    int tempScore=0;
    Object tempModel=getModel();
    //some interesting stuff modifying value of tempScore
    if(tempScore>score)
    {
        score=tempScore;
        model=tempModel;
    }
}

我想使用 Parallel 进行正常的 insted,但我担心我会遇到一些同步问题。我知道我可以使用 lock(model),但是对于简单类型分数我能做些什么呢? model 和 score 是方法局部变量,因此它们在线程之间共享。

【问题讨论】:

  • sn-p 不够清晰。考虑线程局部变量。基本的操作方法文章在这里:msdn.microsoft.com/en-us/library/dd460703.aspx
  • 我们需要知道哪些变量是线程间共享的。我们可以猜测score 是共享的。您可以在 map/reduce 算法中使用线程本地分数。或者您可以使用联锁操作。或锁定。

标签: c# .net for-loop parallel-processing


【解决方案1】:

如果您使用lock (model),并不意味着其他线程将无法访问model。这意味着两个线程将无法同时执行受lock (model) 保护的部分。因此,您也可以使用 lock (model) 之类的东西来保护对 score 的访问。

但是在这种情况下不起作用。 lock 不锁定变量,它锁定对象,然后您修改 model 在循环中引用的对象。因此,我认为最好的选择是创建另一个对象并锁定它:

object model;
int score;
object modelLock = new object();

Parallel.For(…, (…) =>
{
    int tempScore=0;
    Object tempModel=getModel();
    //some interesting stuff modifying value of tempScore
    lock (modelLock)
    {
        if(tempScore > score)
        {
            score=tempScore;
            model=tempModel;
        }
    }
});

如果您发现这对于您的需求来说太慢了(因为使用lock 确实有一些开销,这对您来说可能很重要),您应该考虑使用类似Thread.VolatileRead()Interlocked.CompareExchange() 的东西。但是要非常小心它们,因为很容易让你的代码出现细微的错误。

【讨论】:

  • 非常感谢!看起来 VolatileRead 正是我想要的,而且它有效!
猜你喜欢
  • 1970-01-01
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多