使用 python multiprocessing.Pool 进入睡眠状态的子进程

Posted

技术标签:

【中文标题】使用 python multiprocessing.Pool 进入睡眠状态的子进程【英文标题】:Subprocess gone sleeping with python multiprocessing.Pool 【发布时间】:2021-10-01 07:43:41 【问题描述】:

我用 python 的多处理库编写了一个数据分析程序以实现并行性。由于我不需要详细控制子流程,因此为了简单起见,我使用了 multiprocessing.Pool。

但是,在运行程序时,我发现所有子进程在短暂的活动(运行)状态后都进入状态S(睡眠)。

我调查了wchan 的进程。父进程和除一个子进程外的所有子进程都在等待_futex,另一个在等待pipe_wait

关于我的程序的一些信息:

    我使用multiprocessing.Pool#map 分配任务。 子进程任务包含磁盘IO和高内存使用。在程序运行过程中,子进程的内存消耗可能会超过内存容量(32个子进程,每个子进程最多占用5%的内存)。磁盘空间充足。 映射函数的参数和返回值不是很大(具体来说就是要处理的文件的文件名)。 我没有在我的代码中明确创建任何管道。

这是我的程序的代码骨架。

# imports emitted
def subprocess_task(filename):
  read_the_file(filename) # Large disk IO
  process_the_data() # High memory cost
  write_the_file(new_filename) # Large disk IO
  return newfile_name

if __name__=="__main__":
  files=["","",...] # The filename of files to process, len(files)=32.
  p=multiprocessing.Pool(32) # There are more than 32 cores on the computer.
  res=p.map(subprocess_task,files)
  p.close()
  # Do something with res.

所以我想知道为什么进程会陷入这种状态(尤其是pipe_waiting 那个)?和内存占用高有关系吗,如何解决?

非常感谢!

【问题讨论】:

首先尝试Pool(1),看看单个进程是否可以工作。接下来你可以检查Pool(2)是否有问题。也许您使用的代码阻止了对某些资源的访问,而其他进程等待资源 - 它们永远等待,因为其他进程一直保留它。 【参考方案1】:

好的,经过一番努力挖掘管道(7),multiprocessing源代码和我的麻烦程序的日志,我终于找到了问题。

pipe_wait 的唯一子进程似乎很可疑,因此我浪费了数小时试图找到阻塞管道。但是,关键问题与管道无关。

当我在程序的某些检查点放置一些print 报告pid 时,问题就解决了。提交任务(我将其称为原始流程)和程序卡住时(称为卡住流程)的流程是不同的。原来的 32 个子进程之一在卡住的进程中丢失了,并且提交任务时唯一的卡住进程 pipe_wait 不存在。

所以我现在可以猜到原因了。而multiprocessing的源码和我的猜测相符。

正如我所说,该程序会消耗大量内存。在系统内存不足的某个时刻,OOM killer 会杀死某个特定algorithm 选择的子进程之一。 OOM杀手被强制退出,所有整理都撤消了,包括与multiprocessing.Pool的通信。

正如源代码所示,池使用一个线程来收集任务结果,而另一个线程来管理工作人员。 Collector线程被动等待子进程发送结果,Worker Manager线程通过轮询所有进程主动检测进程退出。

因此,在进程被杀死后,工作管理器线程会检测到它,并通过生成一个新进程来重新填充池。由于没有更多的任务被提交,进程是pipe_wait 一些新的任务。这是我的问题中唯一的 pipe_wait 子进程。同时,结果收集器线程一直在等待被杀死线程的结果,永远不会到达。所以其他线程也在休眠。

我没有对环境的 root 访问权限,或者这可以通过调查 OOM 杀手日志来进一步验证。

【讨论】:

以上是关于使用 python multiprocessing.Pool 进入睡眠状态的子进程的主要内容,如果未能解决你的问题,请参考以下文章

Python系列之 - multiprocessing

python multiprocessing模块 介绍

python MultiProcessing标准库使用Queue通信的注意要点

第52天:python multiprocessing模块

第52天:python multiprocessing模块

python中multiprocessing模块