C# 具有MaxDegreeOfParallelism和实际线程数的ParallelOptions
您好,我正在使用不同的C# 具有MaxDegreeOfParallelism和实际线程数的ParallelOptions,c#,.net,multithreading,parallel-processing,console-application,C#,.net,Multithreading,Parallel Processing,Console Application,您好,我正在使用不同的MaxDegreeOfParallelism方法值执行“动态”多线程处理,但每当我尝试更改MaxDegreeOfParallelism的值时,该值大于1,它会在控制台中显示程序使用的线程比我分配的多 public static string DoMultipleTasks(int threads, List<string> inputList) { ParallelOptions po = new ParallelOptions(
MaxDegreeOfParallelism
方法值执行“动态”多线程处理,但每当我尝试更改MaxDegreeOfParallelism
的值时,该值大于1,它会在控制台中显示程序使用的线程比我分配的多
public static string DoMultipleTasks(int threads, List<string> inputList)
{
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = threads;
Parallel.ForEach(inputList, po, values =>
{
Console.WriteLine(" Name: {0}, Thread Id= {1}", values, Thread.CurrentThread.ManagedThreadId);
});
return null;
}
publicstaticstringdomultipletasks(int-threads,List-inputList)
{
ParallelOptions po=新的ParallelOptions();
po.MaxDegreeOfParallelism=螺纹;
Parallel.ForEach(inputList,po,value=>
{
WriteLine(“名称:{0},线程Id={1}”,值,Thread.CurrentThread.ManagedThreadId);
});
返回null;
}
输出:
MaxDegreeOfParallelism
指定可以同时运行多少线程(或者更确切地说,任务)。它没有指定应该是哪个线程
从:
获取或设置此ParallelOptions实例启用的最大并发任务数
在执行Parallel.ForEach
的过程中,可以在许多不同的线程上运行(因此涉及许多不同的线程id)。这取决于底层线程调度程序
但是,可以保证您的代码块最多同时执行MaxDegreeOfParallelism
虽然您基本上已经有了一个示例,但这里有一个稍微修改的代码版本来说明我的意思
var dict = new ConcurrentDictionary<int, string>();
var po = new ParallelOptions { MaxDegreeOfParallelism = 3 };
int count = 0, maxval = 0;
Parallel.ForEach(Enumerable.Range(1, 10000000), po, (d) =>
{
Interlocked.Increment(ref count);
dict.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, "", (id, old) => old);
lock (dict)
{
maxval = Math.Max(maxval, count);
}
Interlocked.Decrement(ref count);
});
Console.WriteLine("Count: " + count);
Console.WriteLine("Max: " + maxval);
Console.WriteLine("Thread ids: " + String.Join(", ", dict.Select(d => d.Key)));
var dict=新的ConcurrentDictionary();
var po=新的并行选项{MaxDegreeOfParallelism=3};
整数计数=0,最大值=0;
Parallel.ForEach(可枚举范围(1100000),po,(d)=>
{
联锁增量(参考计数);
dict.AddOrUpdate(Thread.CurrentThread.ManagedThreadId,“,(id,旧)=>旧版);
锁(dict)
{
maxval=Math.Max(maxval,count);
}
联锁。减量(参考计数);
});
控制台写入线(“计数:+Count”);
控制台写入线(“Max:+maxval”);
Console.WriteLine(“线程ID:”+String.Join(“,”,dict.Select(d=>d.Key));
其结果应与以下类似:
计数:0最大值:3
线程ID:1、4、5、6、7、8、9
无论您运行此代码多少次,最大值都不应超过3。另一方面,线程ID将经常更改。不确定下一票。如果有任何不清楚的地方,请告诉我。:)谢谢你的回答,这不是我的反对票。现在一切都清楚了,但我仍然不明白为什么程序在多线程上比在单线程上运行得慢。当您想要加快代码的执行速度时,多线程并不总是答案。在您的示例中,调用
Console.WriteLine
,它必须同步对控制台的写入,以避免产生乱码结果。因此,即使您使用多个线程,它们最终还是会互相等待。因此,为了同步打印消息,您增加了更多开销(线程管理)。另一方面,如果您需要对集合中的每个值执行大量CPU繁重的工作(这就是花费时间的地方),那么线程可能是加速它的一个很好的选择。但是在一小段代码中使用三种不同的同步机制可能有点过于匹配(并发收集+锁定
++互锁
)。但它仍然不是线程安全的。行maxval=Math.Max(maxval,count)
您应该使用上一次联锁
调用返回的本地计数
,而不是访问主动变异的共享值。