对于Task.Factory.StartNew和Parallel.Invoke,线程可以在不同的处理器或核心上运行。

6
我希望澄清我对.NET多线程的理解,特别是哪些.NET方法会创建线程,在多处理器/核心系统中可能同时执行。在.NET TPL框架中,您可以使用Parallel.Invoke或Task.Factory.StartNew方法实现某种形式的并行性。我理解,在两种情况下,.NET都会创建新的任务(在Parallel.Invoke背后),然后.NET环境会将这些任务分配给管理线程,这些线程然后被分配到CPU上,根据工作负载可能分配到不同的核心或处理器上。两种方法之间的主要区别在于语义-Parallel.Invoke执行多个任务并等待它们完成;Task.Factory.StartNew在后台启动一个新任务。在两种情况下,实际工作可能在不同的核心或处理器上完成。根据任务并行库(TPL)。我有一个同事坚信只有Parallel.Invoke方法允许线程在不同的核心/处理器上执行,而Task.Factory.StartNew会启动一个新线程,但该线程只会在一个核心/处理器上调度-因此实际上没有提供并行性。
我找不到任何明确说明这一点的文档或文章。我的同事给我推荐了和我正在查看的相同的文章,例如基于任务的异步编程,我认为这些文章证实了我的理解,但是我的同事认为证实了他的理解。
有时候文档会在引用Parallel.Invoke时使用术语“并行处理”,在引用“Task.Factory.StartNew”时使用“异步任务”,但据我所知,关于分配到多个处理器/核心方面,背后发生的事情都是相同的。
如果可能的话,请有人帮助澄清这种情况,并提供文档/文章链接。
我知道这听起来像是在寻求解决与同事的争论,但我真的想澄清我是否正确理解了这个问题。

8
首先,你的同事是错误的。其次,作为人生小贴士,不要浪费时间试图证明错误同事的错误。相反,要求他们提供他们观点的证据 - 把证明的责任推给他们。 - mjwills
可能是如何确定线程运行在哪个CPU上?的重复问题。 - mjwills
2
把你的对手引荐到.NET源代码,其中包括Parallel.InvokeTask.Factory.StartNew - noseratio - open to work
2个回答

4

回答其实很简单。

Task.Run()

将指定的工作排队以在线程池上运行....

任务并行库

...此外,TPL处理工作的分区,调度线程在线程池上,....

如何使用相同的线程池确定任务类型以限制CPU?它们都在所有处理器上运行还是全部在单个处理器上运行。

额外加分:

这引出了一个问题,线程池是否支持多核?

答案令人惊讶,线程池不关心这个。线程池向操作系统请求一个线程(就像使用new Thread()的任何C#应用程序一样),它实际上是操作系统的责任。我认为现在已经非常清楚,即使建议C#可以默认限制如何使用线程,这也是一个非常荒谬的说法,因为有所有这些抽象。(是的,你可以在任何核心上运行线程等等,但这不是ThreadPool的默认工作方式)。
我强烈建议阅读StartNew is Dangerous... TLDR?使用Task.Run()

0

尽管操作系统有时提供“处理器亲和性”,但这是一种边缘情况,其使用(或可用性)相当罕见。据我所知,.NET不使用此类功能。

您的基本假设必须始终是:“可运行的线程/进程将在它想要的地方运行”,并且它可能随时从一个CPU资源切换到另一个。 .NET框架在许多方面使事情变得更加“友好”,但底层调度决策仍然是由主机操作系统独家制定的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接