NET中的去中心化任务调度技术

本文关键字:任务调度 技术 中心化 NET | 更新日期: 2023-09-27 18:26:58

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

我最近又一次回顾了并行模式和实践,有点被去中心化调度技术部分所吸引,该部分简要介绍了"工作窃取"和本地与全局线程队列。

我的问题是:

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

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

NET中的去中心化任务调度技术

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

偷工作是默认的。在.NET 4.0中,ThreadPool扩展了工作窃取行为。默认的TaskScheduler(System.Threading.Tasks.ThreadPoolTaskScheduler)基于ThreadPool类。所以它是默认的,从4.0开始。

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

正如@Servy已经提到的,为了完全控制,你需要编写自己的TaskScheduler。(如"如何:创建限制并发的任务调度器"中所述)

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

  • LongRunning:任务在Treadpool外获取新创建的线程
  • 偏好公平:新的子任务(通常会在执行父任务的线程的本地队列中结束)将在全局队列中结束。因此,如果所有任务都标记为"偏好公平",则工作窃取和本地排队将被有效地停用

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

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

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