[英]Does Task Parallel Library (TPL) handle race condition
I am trying to understand the benefits of Task Parallel library over using traditional multi threading and when I think about the below situation, I am stuck thinking does it handle race condition or do we need to handle this in our code?我试图了解 Task Parallel 库相对于使用传统多线程的好处,当我考虑以下情况时,我陷入了思考它是处理竞争条件还是我们需要在我们的代码中处理这个问题?
Here is my code:这是我的代码:
int depdt = 0;
Parallel.For(1, 10, mem =>
{
for (int dep = 1; dep <= 10; dep++)
{
depdt = dep;
Console.WriteLine("MEMBER: " + mem + " " + "Dependent: " + dep);
}
Console.WriteLine("Dep Value: " + depdt + " " + "mem: " + mem);
});
Console.ReadKey();
I ran it couple of times and I don't see any thread interfering/overwriting the the "depdt" variable.我运行了几次,但没有看到任何线程干扰/覆盖“depdt”变量。 But I need to confirm this.但我需要确认这一点。 (or) To make it thread safe should I manually create an instance of class and implement it like the below code to avoid race conditions (或)为了使其线程安全,我应该手动创建一个类的实例并像下面的代码一样实现它以避免竞争条件
int depdt = 0;
Parallel.For(1, 10, mem =>
{
Worker worker = new Worker();
worker.DoWork(mem);
});
Console.ReadKey();
public class Worker
{
public void DoWork(int mem)
{
int depdt = 0;
for (int dep = 1; dep <= 10; dep++)
{
depdt = dep;
Console.WriteLine("MEMBER: " + mem + " " + "Dependent: " + dep);
}
Console.WriteLine("Dep Value: " + depdt +" "+ "mem: "+ mem);
}
}
Response to @yms: I mean when using normal threads the varaible depdt becomes unreliable.对@yms 的回应:我的意思是当使用普通线程时,可变的 depdt 变得不可靠。 Here is my code:这是我的代码:
for (int mem = 1; mem <= 10; mem++)
{
var t= new Thread(state =>
{
for (int dep = 1; dep <= 10; dep++)
{
depdt = dep;
Console.WriteLine("MEMBER: " + mem + " " + "Dependent: " + dep);
}
Console.WriteLine("Dep Value: " + depdt + " " + "mem: " + mem);
});
t.Start(string.Format("Thread{0}", mem));
}
Console.ReadKey();
Here is my output screen: Infact both mem and dep variables have become unreliable这是我的输出屏幕:事实上,mem 和 dep 变量都变得不可靠了
If you expect your program to always write Dep Value: 10
, then yes, your program is subject to a race condition that may lead to other values being printed.如果您希望您的程序始终写入Dep Value: 10
,那么是的,您的程序会受到可能导致打印其他值的竞争条件的影响。 To demonstrate the issue, just introduce a delay within the inner loop:为了演示这个问题,只需在内部循环中引入一个延迟:
int depdt = 0;
Parallel.For(1, 10, mem =>
{
for (int dep = 1; dep <= 10; dep++)
{
depdt = dep;
Console.WriteLine("MEMBER: " + mem + " " + "Dependent: " + dep);
Thread.Sleep(mem * 100); // delay introduced here
}
Console.WriteLine("Dep Value: " + depdt + " " + "mem: " + mem);
});
Console.ReadKey();
The reason that your program appears to behave correctly is that the inner loop takes very little time to execute, probably completing within a single time quantum allocated to the thread.您的程序似乎行为正确的原因是内循环执行时间非常短,可能在分配给线程的单个时间量程内完成。
To avoid the race condition, you just need to move the depdt
declaration inside the anonymous function passed to Parallel.For
.为了避免竞争条件,你只需要移动depdt
传递给匿名函数内声明Parallel.For
。 This would cause each thread to have its own variable, avoiding conflicts.这将导致每个线程都有自己的变量,从而避免冲突。
Parallel.For(1, 10, mem =>
{
int depdt = 0;
for (int dep = 1; dep <= 10; dep++)
{
depdt = dep;
Console.WriteLine("MEMBER: " + mem + " " + "Dependent: " + dep);
}
Console.WriteLine("Dep Value: " + depdt + " " + "mem: " + mem);
});
No. Task parallel library does not handles the race conditions by default.否。默认情况下,任务并行库不处理竞争条件。 You need to take care of synchronizing the access to the shared resources.您需要注意同步对共享资源的访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.