[英]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.