c# - 并行操作的线程安全

标签 c# multithreading parallel-processing thread-safety

在开始之前,我应该提一下,我觉得我搞错了方向。但无论如何,我们还是开始吧:

假设我们有以下类(class):

public class SomeObject {
    public int SomeInt;
    private SomeObject anotherObject;

    public void DoStuff() {
        if (SomeCondition()) anotherObject.SomeInt += 1;
    }
}

现在,假设我们有这些 SomeObject 的集合s:

IList<SomeObject> allObjects = new List<SomeObject>(1000);
// ... Pretend the list is populated with 1000 SomeObjects here

假设我打电话 DoStuff()在每一个上,就像这样:

foreach (var @object in allObjects) @object.DoStuff();

到目前为止一切都很好。 现在,我们假设对象的顺序是 DoStuff()叫什么并不重要。假设SomeCondition()也许在计算上是昂贵的。我可以利用我的机器上的所有四个核心(并可能获得性能提升):

Parallel.For(0, 1000, i => allObjects[i].DoStuff());

现在,忽略变量访问原子性的任何问题,我不在乎在循环中是否有任何给定的 SomeObject看到 anotherObject 的过时版本或SomeInt .* 但是,一旦循环完成,我想确保我的主工作线程(即调用 Parallel.For 的线程)确实看到所有内容都是最新的。

使用 Parallel.For 是否能保证这一点(例如某种内存屏障?)?还是我自己需要做某种保证?或者说没有办法做出这样的保证?

最后,如果我调用Parallel.For(...)之后再次以同样的方式,所有工作线程都会使用新的、最新的值吗?


(*) DoStuff() 的实现者无论如何,对处理顺序做出假设都是错误的,对吗?

最佳答案

        var locker = new object();
        var total = 0.0;
        Parallel.For(1, 10000000,
        i => { lock (locker) total += (i + 1); });
        Console.WriteLine("WithLocker" + total);

        var total2 = 0.0;
        Parallel.For(1, 10000000,
        i => total2 += (i + 1));
        Console.WriteLine("WithoutLocker" + total2);
        Console.ReadKey();

        // WithLocker 50000004999999
        // WithoutLocker 28861729333278

我为你做了两个例子,一个带储物柜,一个不看结果!

关于c# - 并行操作的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18677539/

相关文章:

java - 如何停止可运行的线程

c# - 如何在 MVC 4 中添加 View

c# - 是否可以在 monotuch 中调用委托(delegate)?

c# - MSBuild web.config 转换不工作

c# - 如果花费的时间太长,则取消执行命令

c# - Thread.IsAlive 和 Thread.ThreadState==ThreadState.Running

ruby - Ruby 中的多线程编程

python-3.x - 如何在不使用光线模式的情况下以平行光线运行函数?

c# - Azure 存储表 : await table. ExecuteAsync(InsertOperation) 执行,但从未完成

.net - 在 TPL 中复制队列