5

我正在阅读有关 Thread 和 Task 之间区别的问题。我有这个链接可以继续阅读:MSDN上的任务计划程序

但我对这一段感到困惑:

在某些情况下,当等待一个任务时,它可能会在执行等待操作的线程上同步执行。这提高了性能,因为它通过利用本来会阻塞的现有线程来防止需要额外的线程,否则。为了防止由于重入而导致的错误,任务内联仅在相关线程的本地队列中找到等待目标时发生。

我想了解突出显示的部分。此外,我的本地缓存和全局队列也有点混乱......我真的很想了解TaskScheduler......请帮助......

4

2 回答 2

2

首先,什么是本地队列和全局队列?这是 .Net 4.0 中并行处理的优化。如果您有很多 small Tasks 并且只有一个全局队列,那么您会遇到很多争用。这是因为所有线程都Task从同一个地方(全局队列的前面)处理 s,并且它们也将新Task的 s 放到同一个地方(全局队列的后面)。这需要线程之间的大量同步,这会影响性能。

.Net 4.0 中的 TPL 使用了一种称为“工作窃取”的技术:和以前一样,有一个全局队列,每个ThreadPool工作线程(但不是其他线程)也有一个本地队列。如果非工作线程启动 a Task,它会像以前一样进入全局队列的后面。如果工作线程启动 a Task,它将进入其本地队列的后部。

现在到有趣的部分。如果一个工作线程应该处理一个新的Task,它会在这些地方寻找它(按这个顺序):

  1. 本地队列的尾部
  2. 全局队列的前面
  3. 其他线程的本地队列的前面

最后一部分是为什么这被称为“工作窃取”:工作线程可以“窃取” aTask以从另一个线程进行处理。线程不需要使用同步来访问其本地队列的尾部,因为没有其他线程可以访问它。并且在本地以 LIFO 顺序处理Tasks 也有利于缓存,因为最后一个Task(以及它使用的数据)最有可能仍在 CPU 缓存中。

有关这一切的另一种解释(带图片),请参阅.NET 4.0 中的 Work-Stealing


这与内联和重入有什么关系?我不知道。如果 s 使用一些线程静态字段,我可以理解为什么会出现重入问题Task,但这与队列无关。无论内联Task来自哪个队列,都可能发生此问题。我想不出任何Task可以保证本地队列中的 s 可以安全内联的情况,但Task其他队列中的 s 可能不安全。

于 2012-08-21T09:18:49.133 回答
2
于 2012-08-21T09:21:26.587 回答