Python 3.x 多处理池-内存使用

Python 3.x 多处理池-内存使用,python-3.x,memory,multiprocessing,Python 3.x,Memory,Multiprocessing,我编写了一个脚本,部署在一个拥有112个内核的HPC节点上,因此启动了112个进程,最多完成了400个所需的进程(node\u compositions是一个包含400个元组的列表)。下面是相关的代码片段: # Parallel Path Probability Calculation # ===================================== node_combinations = [(i, j) for i in g.nodes for j in g.nodes] poo

我编写了一个脚本,部署在一个拥有112个内核的HPC节点上,因此启动了112个进程,最多完成了400个所需的进程(
node\u compositions
是一个包含400个元组的列表)。下面是相关的代码片段:

# Parallel Path Probability Calculation
# =====================================
node_combinations = [(i, j) for i in g.nodes for j in g.nodes]
pool = Pool()
start = datetime.datetime.now()
logging.info("Start time: %s", start)
print("Start time: ", start)
pool.starmap(g._print_probability_path_ij, node_combinations)
end = datetime.datetime.now()
print("End time: ", end)
print("Run time: ", end - start)
logging.info("End time: %s", end)
logging.info("Total run time: %s", start)
pool.close()
pool.join()
我通过运行
htop
来跟踪性能,并观察以下内容。最初,所有112个核心都在100%工作。最终,由于某些进程比其他进程短,所以我只剩下少量的内核以100%的速度工作。最终,所有进程都显示为休眠

我认为问题在于,其中一些进程(需要更长时间的进程,大约400个进程中的20个进程)需要大量内存。当内存不足时,进程进入睡眠状态,因为内存从未被释放,所以它们仍在那里,处于睡眠状态。以下是我的问题:

  • 一旦一个进程完成,资源(读内存)会被释放还是会一直被占用直到所有进程完成?换句话说,一旦我只有20个内核在工作(因为其他内核已经处理了所有较短的进程),那么它们是否可以访问所有内存,或者只访问其余进程未使用的内存

  • 我已经读到
    maxtasksparchild
    在这种情况下可能会有所帮助。那怎么办?如何确定每个孩子的适当任务数


  • 如果您想知道我为什么要问这个问题,那是因为在我阅读的文档中:版本2.7中的New:maxtasksperchild是工作进程在退出并替换为新工作进程之前可以完成的任务数,以释放未使用的资源。默认的maxstasksperchild为None,这意味着工作进程将与池一样长。

    您应该让至少一个内核可供核心操作系统使用,另一个可供启动脚本使用;试着减少你的游泳池大小。e、 g.游泳池(110)

    使用Pool.imap(或imap_unordered)代替Pool.map。这将比在开始处理之前将所有数据加载到内存中更慢地迭代数据

    将值设置为maxtasksperchild参数

    使用多处理池时,将使用fork()系统调用创建子进程。这些进程中的每一个都从父进程当时的内存副本开始。因为在创建池之前加载元组列表,所以池中的进程将拥有数据的副本


    答案是通过内存分析的方法,这样您就可以看到内存在何时何地。

    您应该让至少一个内核可供核心操作系统使用,另一个可供启动脚本使用;试着减少你的游泳池大小。e、 g.游泳池(110)

    使用Pool.imap(或imap_unordered)代替Pool.map。这将比在开始处理之前将所有数据加载到内存中更慢地迭代数据

    将值设置为maxtasksperchild参数

    使用多处理池时,将使用fork()系统调用创建子进程。这些进程中的每一个都从父进程当时的内存副本开始。因为在创建池之前加载元组列表,所以池中的进程将拥有数据的副本


    答案是通过一种内存分析方法得出的,这样您就可以看到内存在何时何地运行。

    进程不休眠。它们只会引发内存不足异常。因为他们已经引发了某种异常,他们可能还没有到达代码的末尾,这将使他们做好加入的准备。如果他们引发了异常,为什么我的代码没有失败?一旦只剩下20份最长的工作,他们最终就睡着了。它不会因为内存不足而失败。失败的未连接进程只会阻塞,直到它可以连接为止。它不是在睡觉,它陷入了一个未经处理的错误,导致死锁。有什么办法可以处理吗?我的意思是,一旦资源被释放,我能以某种方式重新启动这些过程吗?我一直在监控进度,当资源可用时,流程不会重新启动。什么都没发生…你可以通过几种方式。。。这取决于你的最终目标是什么。实际上,您应该尽量避免开始时内存不足(可能是一些策略性放置的del语句),或者确定某个特定进程是否能够为其分配足够的ram(如果不能,则将其放回队列)。另一件事是实际处理进程中的内存不足错误,然后将它们提交给调度程序,以便在可能的情况下重新排队或拆分工作负载进程不睡眠。它们只会引发内存不足异常。因为他们已经引发了某种异常,他们可能还没有到达代码的末尾,这将使他们做好加入的准备。如果他们引发了异常,为什么我的代码没有失败?一旦只剩下20份最长的工作,他们最终就睡着了。它不会因为内存不足而失败。失败的未连接进程只会阻塞,直到它可以连接为止。它不是在睡觉,它陷入了一个未经处理的错误,导致死锁。有什么办法可以处理吗?我的意思是,一旦资源被释放,我能以某种方式重新启动这些过程吗?我一直在监控进度,当资源可用时,流程不会重新启动。什么都没发生…你可以通过几种方式。。。这取决于你的最终目标是什么。实际上,您应该尽量避免开始时内存不足(可能是一些策略性放置的del语句),或者确定某个特定进程是否能够为其分配足够的ram(如果不能,则将其放回队列)。另一件事是实际处理进程中的内存不足错误,然后将它们提交给调度程序,以便在可能的情况下重新排队或拆分工作负载