【问题标题】:How pool.map() allocates the work internally?pool.map() 如何在内部分配工作?
【发布时间】:2017-09-22 09:19:11
【问题描述】:

我对@9​​87654322@ 库很陌生,并且在与map() 一起使用时对其Pool 模块有疑问。假设我有 4 个工作线程和 6 个任务要完成。我所做的是(使用multiprocessing.dummy,因为我想生成线程而不是进程)

from multiprocessing.dummy import Pool as ThreadPool

def print_it(num):
    print num

def multi_threaded():
    tasks = [1, 2, 3, 4, 5, 6]
    pool = ThreadPool(4)
    r = pool.map(print_it, tasks)
    pool.close()
    pool.join()

multi_threaded()

我想了解 Pool.map() 如何处理任务?三个选项:

  1. 它是否首先产生 4 个线程,完成前 4 个任务并让线程终止。然后为剩余的任务生成 2 个新线程?
  2. 它是否产生 4 个线程,为它们分配 4 个任务,一旦某个线程完成其任务,将新任务分配给同一线程。
  3. 其他方式。

这种见解会很有帮助,因为它将帮助我考虑在产品中更有效地使用 Pool.map()

【问题讨论】:

  • 我所知道的几乎所有池子都是(2)。但我不知道这个特定的库,通常我对 python + 多线程的东西主要是令人失望的经历。我认为一些有限的智能解决方案是很有可能的。祝你好运,得到详细的答案。
  • 您可以通过将print_it 函数也设为sleep 来进行测试,看看会发生什么。在 Python 3.6 中进行此测试时,似乎只要有空闲线程来处理新任务就会开始。
  • 为什么不read the source 自己看看? ThreadPool 类是普通 multiprocessing.pool.Pool 的子类,它覆盖了一些东西(如果需要,可以在文件底部查看它的定义)。

标签: python threadpool python-multiprocessing


【解决方案1】:

这取决于您如何定义您的游泳池。

当您在示例中执行此操作时,您的 (2) 会发生。初始化 Pool 后,依赖于 Pool 的线程或进程会立即启动(发生在 Pool__init__() - 无需为此提交任务)并且它们坐在那里等待任务。当任务到达并执行时,线程或进程不会退出,它们只是回到等待状态等待更多工作的到来。

不过,您可以定义不同的工作方式。您可以将maxtasksperchild 参数添加到您的池中。一旦一个worker完成了这么多任务,它就会退出,并立即启动一个新的worker(不需要先给它一个任务,只要一个worker退出它就会启动)。这是在 Pool 类 Pool._maintain_pool()Pool._repopulate_pool() 函数中管理的。

如果您希望您的工作人员在启动时启动并无限期运行,请执行您现在所做的事情,这就是发生的事情。如果您希望您的工作人员在开始时启动,但在完成多项任务后退出并更新自己(即使是必要的一项),请使用maxtasksperchild。如果您不想在需要之前启动进程或线程,请不要使用 Pool。在需要时启动线程或进程并自行管理它们。

希望这会有所帮助。

【讨论】:

  • 这是一个绝妙的答案。谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 2019-01-13
相关资源
最近更新 更多