c# c#多线程循环 - Parallel.ForEach是否限制活动线程的数量?




c#多线程并行 (5)

不,它不会启动1000个线程 - 是的,它会限制使用多少个线程。 并行扩展使用适当数量的核心,这取决于您实际拥有多少核心以及多少核心已经繁忙。 它为每个内核分配工作,然后使用称为“ 工作窃取”的技术,让每个线程都有效地处理自己的队列,并且只需要在需要时执行任何昂贵的跨线程访问。

查看PFX团队博客 ,了解关于如何分配工作和各种其他主题的大量信息。

请注意,在某些情况下,您也可以指定所需的并行度。

鉴于此代码:

var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
    DoSomething(someString);
});

所有1000个线程几乎同时产生?



它根据处理器/内核的数量计算出最佳线程数。 他们不会一次全部产卵。


在单个核心机器上... Parallel.ForEach分区(块)是它在多个线程之间工作的集合,但是该数字是基于算法计算的,该算法考虑到并似乎持续监视由线程将分配给ForEach。 因此, 如果ForEach的主体部分调用长时间运行的IO绑定/阻塞函数,这会使线程等待,算法会产生更多的线程并重新分配它们之间的集合 。 如果线程快速完成并且不会在IO线程上阻塞,例如简单地计算一些数字, 则算法会将线程数提高(或确实下降)到算法认为吞吐量最佳的点(平均完成每次迭代的时间)

基本上,所有各种并行库函数的后面的线程池都可以找出最佳线程数量来使用。 物理处理器内核的数量仅构成等式的一部分。 核心数量和产生的线程数量之间并不存在简单的一对一关系。

我没有找到关于取消和处理同步线程的文档,这非常有帮助。 希望MS可以在MSDN中提供更好的示例。

不要忘记,正文代码必须写成在多个线程上运行,以及所有常见的线程安全考虑,框架不会抽象出这个因素。


你也可以做到这一点

[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3
}

我发现比输入4,8,16,32等位移更容易。 它对你的代码没有影响,因为它都是在编译时完成的





c# .net c#-4.0 parallel-processing