【问题标题】:Duplicating queue in TPL在 TPL 中复制队列
【发布时间】:2011-05-21 13:45:48
【问题描述】:

我正在研究 .NET (TPL) 的任务并行库,我试图了解它是如何工作的,我理解工作窃取的想法,但我不明白为什么我们使用复制队列以及它是如何工作的?

当新任务被创建时,谁来指定哪个线程应该接受它并将它放入它的任务队列?

你能帮帮我吗?

【问题讨论】:

  • 什么是“复制队列”?您是如何确定 TPL 使用的?
  • 我在这个 pdf 中读到过它:google.com/…
  • 感谢链接,读起来很有趣。
  • 您的问题到底是什么?您是在问复制队列是如何工作的吗?你问如何使用TPL?还有什么?

标签: .net parallel-processing task-parallel-library


【解决方案1】:

假设您自己实现了 TPL,并使用了普通的非重复工作窃取队列。因此,对于每个队列,您有一个线程可以从队列尾部推送和弹出,并且可以从队列头部获取多个线程(在论文中称为窃贼)。因为您想确保添加到队列中的每个任务都只删除一次(通过弹出或获取),所以您必须在这三个操作中的每一个中使用锁定。

在某种程度上,当你知道只有一个线程会使用这些操作时,锁定 push 和 pop 似乎很浪费。但是,如果您想确保队列正常运行,您无能为力。

您的库工作正常,但您意识到经常发生的情况是您正在等待一个甚至还没有开始的任务。那么,在当前线程中同步运行呢?你可以这样做,但问题是任务在某个队列中,你不能安全快速地从那里删除它。您可以做的是向任务添加一个标志,指示其状态,并以线程安全的方式访问该标志。

这样,如果您最终将任务出队,您将不会运行它,因为您知道它已经在运行甚至完成。队列呢?我们说我们想确保我们从队列中删除任务恰好一次。但这不再是必需的:如果我们将某个任务删除两次,这无关紧要,因为该任务会自己处理它并且实际上只会启动一次。

但这意味着我们可以从 pop 和 push 中移除锁,从而导致重复队列,这比普通的工作窃取队列更快,因为它的要求较弱:我们可以确保每个任务都从中移除 至少一次。

编辑:对问题的反应:

通过采取移除任务是可以的,但是通过将任务推入队列来移除任务!

抱歉,这是一个错误,现在已修复。它正在弹出或服用。

第 6 页 fib 示例中的案例 3,是吗?

是的。

为什么?我无法理解这个问题。

问题是,此任务可能在任何线程的队列中,或者它当前可能正在任何线程上执行。因此,您至少必须搜索每个线程上运行的任务,并为每个线程使用锁。并且每个线程在更改其正在运行的任务时都必须使用锁。如果任务当前未运行,您至少必须锁定要从中删除的队列。这也使得对队列行为的分析更加复杂:现在事情可以从队列中间消失。

从pop和push中删除锁与复制队列之间的逻辑联系是什么?

当您移除锁时,您不能完全确定一个任务是否被移除了一次。可能发生的情况是队列中只有一个任务,并且两个不同的线程同时调用 take 和 pop。因为 pop 不使用锁,所以同一个任务会被移除两次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 2011-03-23
    • 2014-08-14
    相关资源
    最近更新 更多