0

我一直在尝试了解有关 CLR 4.0 的更多详细信息。以及微软推荐的线程池和不同的策略。我认为自己在很多这些主题上都处于最新状态,并且每天都使用线程和并发代码。

最近,我再次回顾了Parallel Patterns and Practices ,对分散式调度技术部分进行了简要介绍,该部分简要概述了“工作窃取”以及本地与全局线程队列。

我的问题是:

1)偷工作是选择加入还是选择退出?使用本地线程队列也一样吗?或者 CLR 4.0 默认情况下会发生这种情况吗?

2)我们是否可以控制我们是使用本地线程队列还是全局线程队列?如果是这样,通过什么 API 调用?

4

2 回答 2

1

1) 偷工作是选择加入还是选择退出?使用本地线程队列也一样吗?或者 CLR 4.0 默认情况下会发生这种情况吗?

工作窃取是默认设置。在 .NET 4.0 中,ThreadPool 被扩展为工作窃取行为。而默认的TaskScheduler(System.Threading.Tasks.ThreadPoolTask​​Scheduler)是基于ThreadPool Class的。所以它是默认的,从 4.0 开始。

2)我们是否可以控制我们是使用本地线程队列还是全局线程队列?如果是这样,通过什么 API 调用?

正如@Servy 已经提到的,要获得完全控制,您需要编写自己的 TaskScheduler。(如如何:创建限制并发的任务计划程序中所述)

但是您可以通过TaskCreationOptions以某种方式影响排队行为:

  • LongRunning:任务在 Treadpool 之外获得一个新创建的线程
  • PreferFairness:新的子任务(通常会在执行父任务的线程的本地队列中结束)将在全局队列中结束。因此,如果所有任务都标有“PreferFairness”,那么工作窃取和本地排队将被有效地停用。

但是,正如这篇关于 PreferFairness的文章所强调的那样,这些标志的实现细节/效果可能会随着 .NET 框架的新实现而改变。

于 2013-08-09T15:45:46.183 回答
0

你也无法控制。这描述了默认线程调度程序如何调度它的任务。这就是它的工作原理。您可以完全创建自己的 TaskScheduler,并从头开始编写自己的调度程序,还可以TaskCreationOptions用来向调度程序提供一些提示(如果需要,可以随意忽略),但这些选项都不允许您指定哪个这些队列中的一个任务进入。

任务模型的主要观点是你不需要担心这些细节;目的是工作可以由任何工作线程以任何顺序调度,并且您允许框架调度程序尽最大努力优化工作。添加常量使它更难有效地做到这一点。如前所述,如果您需要完全不同的算法来调度任务,则可以使用自定义任务调度程序。

于 2013-08-09T15:23:39.307 回答