繁体   English   中英

Parallel.ForEach中的竞争条件?

[英]Race condition in Parallel.ForEach?

以下代码中是否存在可能的竞争条件?

public void Process(List<SomeObject> list)
{
    SomeDataOutput objData=null;
    ConcurrentBag<SomeDataOutput> cbOutput = new ConcurrentBag<SomeDataOutput>();
    ParallelOptions po = new ParallelOptions(){MaxDegreeOfParallelism=4};
    Parallel.ForEach(list, po, (objInput) =>
    {
        objData = GetOutputData(objInput);//THIS LINE IS THE ONE I AM UNSURE OF. CAN objData GET OVERWRITTEN BY MULTIPLE PARALLEL THREADS?
        cbOutput.Add(objData);
    });
}  

是的,可能存在竞争条件。 两个线程可能会在循环体中交错语句,如下所示:

Thread #1                             Thread #2
==================================    ==================================
objData = GetOutputData(objInput);
                                      objData = GetOutputData(objInput);
cbOutput.Add(objData);
                                      cbOutput.Add(objData);

因为objData是在循环外声明的,所以两个线程共享同一个变量。 结果,线程#2覆盖了线程#1设置的objData引用,线程#2的objData被添加到cbOutput两次。

要防止objData被多个线程共享, objData局部变量:

SomeDataOutput objData = GetOutputData(objInput);
cbOutput.Add(objData);

或者你可以完全摆脱变量:

cbOutput.Add(GetOutputData(objInput));

是。

(编辑删除不正确和分散注意力的信息)

正如另一个答案所说,你可以这样做:(这个答案的剩余部分早于我的更正(感谢Ben Voight))。

public void Process(List<SomeObject> list)
{
    ConcurrentBag<SomeDataOutput> cbOutput = new ConcurrentBag<SomeDataOutput>();
    ParallelOptions po = new ParallelOptions(){MaxDegreeOfParallelism=4};
    Parallel.ForEach(list, po, (objInput) =>
    {
        cbOutput.Add(GetOutputData(objInput));
    });
}

而这显然没有覆盖对象或内存的风险。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM