【问题标题】:Thread Pool : how to spawn a child task from a running task?线程池:如何从正在运行的任务中生成子任务?
【发布时间】:2011-05-30 12:22:21
【问题描述】:

具有全局共享任务队列(函子)的简单线程池。

每个工作人员(线程)将从工作人员那里获取一项任务,并执行它。它不会执行下一个任务,直到这个任务完成。

让我们想象一个大任务需要产生子任务来产生一些数据,然后继续进行评估(例如,在保存到磁盘之前对大数组进行排序)。

任务代码的伪代码:

  do some stuff
  generate a list of child tasks
  threadpool.spawn (child tasks)
  wait until they were executed
  continue my task

问题是worker会死锁,因为任务在等待子任务,而线程池在等待父任务结束,才运行子任务。

一个想法是在生成代码中运行子任务:

threadpool.spawn 伪代码:

   threadpool.push (tasks)
   while (not all incoming task were executed) 
      t = threadpool.pop()
      t.run()
   return (and continue executing parent task)

但是,我怎么知道所有任务都以一种有效的方式执行了?

另一个想法是拆分父任务..像这样:

任务伪代码:

  l = generate a list of child tasks
  threadpool.push ( l , high priority )
  t = create a task to work with generated data
  threadpool.push (t , lo priority )

但我发现这很烦人......

有什么意见吗?

pd。圣诞节快乐! PD2。修改了一些不好的名字

【问题讨论】:

  • "问题是worker会死锁,因为任务在等待子任务,而线程池在等待父任务结束,才运行子任务。" - 这是你在做的假设吗?即使有父任务正在运行,也有线程池将运行子任务。 Java Executors 可以做到这一点。
  • 这是什么cr*ppy线程池?需要一个线程在运行另一个线程之前完成的线程池不是线程池。
  • SB: ofc,但我正在用 c++ 编写自己的线程池,我在问如何自己实现该功能
  • Hans Passant:对不起,如果我没有解释自己......“工人”是一个线程,一个任务是一个由每个线程执行的“函子”。线程池将从队列中提取“函子”(任务)并执行它们。在当前任务完成之前,线程不会执行队列中的下一个任务。

标签: multithreading threadpool


【解决方案1】:

您可以有一种机制,让子线程在完成时向主工作线程发出信号,以便它可以继续。在 Java 中,Callable 任务提交到ExecutorService 线程池,并以Futures 数据结构的形式返回结果。另一种方法是维护一个单独的完成信号,类似于CountDownLatch,它将作为一种常见的倒计时机制,每次线程完成时都会更新。

【讨论】:

  • 正如我所说,我使用的是线程池,所以我可以创建的新线程的数量是有限制的。如果我当前的任务阻塞等待其他线程,那么它永远不会退出。我可以发现所有线程都在等待子任务。
猜你喜欢
  • 2016-06-14
  • 2017-04-06
  • 2014-06-14
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2017-01-06
  • 2015-08-06
相关资源
最近更新 更多