在 Python 自带的 multiprocessing 库中, 只有可以被 pickle.dump 的函数才能以 multiprocessing.Pool().map 等形式并行化执行. 而只有定义在模块 top-level 的函数才是 picklable 的. 这是因为在 Pool.map 的内部, 函数是通过 collections.deque 来加入到任务队列的, 而能被添加到 collections.deque 的对象必须是 picklable 的.

对此, 我们可以

  • 定义一个 top-level wrapper 函数来绕过这个问题.
  • 改用 ThreadPool, 但是这会导致 GIL 限制, 所以没什么卵用.
  • 改用其他的并行库来执行, 比如 pathos.
    pathos 的 map 其实也需要函数和参数都能被序列化, 但是其采用的是 dill 库来做这个事情, 而 dill 的序列化能力比自带的 pickle 模块强多了, 甚至可以在交互模式下序列化任意用户定义的函数或者对象. 这也意味着我们可以不用 pathos, 而只用 dill 来写一个 wrapper 函数从而以类似第一个方案的方式来解决问题.