【问题标题】:Correctly shutting down a work stealing thread pool正确关闭工作窃取线程池
【发布时间】:2016-12-23 15:29:27
【问题描述】:

给定一个工作窃取线程池系统,其中每个工作项都可以在线程本地工作队列中生成新任务 - 如果已满,可以溢出到全局队列。

您将如何安全有效地协调此类系统的关闭?假设您只有基本的原子操作和临界区锁可用。

进一步澄清和简化。假设每个线程仅从其本地工作队列中获取任务(为了简化,没有在其他线程队列之间窃取)。如果它的本地工作队列用尽,它将锁定全局工作队列并窃取工作以添加到其本地工作队列中。本地工作队列不需要锁,因为它们特定于每个工作线程。

使用简单的标志或“活动”工作线程的原子计数将不起作用,因为其他工作人员可能会将新工作溢出到全局队列中,而从另一个工作线程看来,它可能认为它是唯一剩下的工作人员工作。

所有工作人员只有在没有工作时才应该退出。

【问题讨论】:

  • 我投票结束这个问题,因为它太宽泛了。我相信您应该关注您的问题并告诉我们您到目前为止所做的尝试。就个人而言,我可能会举起“停止”标志并加入所有线程。这并不保证关闭,因为现有任务可能会永远运行(他们可能会自称)......所以我也会公开标志并在自我更新任务中检查它......我在线程池中做了类似的事情我为服务器写的。
  • 对不起,我认为它非常具体。由于无法保证线程之间何时发生可见性,因此提高停止标志不起作用,也无法对当前活动的工作人员进行简单的原子计数。通过提交自己导致无限循环的任务将是任务设计中的错误,而不是池本身。
  • 有一个具体的问题并不意味着它不是太宽泛。 “太宽泛”是指可能的答案,在您询问“如何...”时,您可能会获得很多关于什么有效的意见。没有“正确”的答案。
  • 我已经编辑了一些更多的说明和简化,如果有帮助的话?
  • 您可能想在Programmer's StackExchange 上尝试这个问题,这通常会迎合更广泛的基于意见的代码设计问题。

标签: c multithreading atomic


【解决方案1】:

最大的要求是通过某种方式保存每个任务的定义,以便可以将待处理任务的状态保存到持久存储中。然后实现一个“停止”标志(上面有一个互斥锁)。从池中获取任务以执行的方法检查该标志,如果已设置,则返回“终止工作线程”指示(与使线程等待并重试的“无可用任务”结果不同)。线程在收到该指示时终止,并且整个池管理线程一直等待,直到所有工作线程都终止,然后终止池。主程序必须等到池终止并且池管理线程退出,一旦发生这种情况,终止程序是安全的。如果程序需要继续运行并稍后重新启动池,这也是必须满足的条件才能执行任何会影响池配置或重新启动池的操作。

【讨论】:

  • 我不知道为什么保存挂起任务的状态是个问题——它们要么在全局或本地工作队列中,要么在工作线程中正在运行的寄存器中。现在也没有整体的池管理线程——只有一个相同的工作线程池。问题是工作人员可以从他们正在运行的任务中生成新任务,这可能会溢出到全局队列中,这会导致有问题的边缘情况,工作人员认为其他人可能已经使用简单的标志或计数器完成了,但实际上有还在工作。
  • @iam 队列中有工作,或者没有工作。为什么工人应该关心其他工人在做什么?看来您的系统过于复杂而无法控制。
  • @iam 没错。需要持久存储,因为要么停止线程生成工作(这意味着它们可能需要停止中间任务),要么阻止它们获取新工作(这意味着队列中未启动的任务)。您需要一个管理线程,因为需要等待工作线程停止,如果它们提前结束则重新启动它们,并跟踪它们是否都已正确关闭以及池何时安全且完全关闭。
猜你喜欢
  • 1970-01-01
  • 2015-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 2011-04-28
相关资源
最近更新 更多