【发布时间】:2018-08-08 13:32:36
【问题描述】:
我一直在试验 Parallel.For。特别是支持线程本地数据的重载,例如
public static System.Threading.Tasks.ParallelLoopResult For (long fromInclusive, long toExclusive, System.Threading.Tasks.ParallelOptions parallelOptions, Func localInit, Func body, Action localFinally);
localInit 委托为参与循环执行的每个线程调用一次
但是我认为我下面的例子与之矛盾
var threads = new ConcurrentBag<int>();
ValueTuple LocalInit()
{
threads.Add(Thread.CurrentThread.ManagedThreadId);
return new System.ValueTuple();
}
ValueTuple Body(long i, ParallelLoopState _, ValueTuple state)
{
Thread.Sleep(100);
return state;
}
void LocalFinally(ValueTuple state) { };
Parallel.For(0L, 1000L, new ParallelOptions(), LocalInit, Body, LocalFinally);
Console.WriteLine($"{threads.Count} inits between {threads.Distinct().Count()} threads");
它打印一条消息,例如
13 个线程之间的 79 个初始化
发生了什么事?
【问题讨论】:
-
你正在阻塞线程,迫使
Parallel.For创建更多线程来处理输入。Parallel.方法用于数据并行。他们会从大致与核心数量一样多的任务开始,如果检测到任务被阻止,则会添加更多任务。 -
一个更好的例子是使用一个大循环和
Body,它实际上做了一些事情,或者一个不让线程进入睡眠状态的 Spinwait
标签: .net task-parallel-library parallel.foreach