【问题标题】:memory leak when using multiprocessing使用多处理时的内存泄漏
【发布时间】:2016-02-06 00:37:01
【问题描述】:

如标题所示,我在使用multiprocessing 时遇到了内存泄漏问题。我知道以前有人问过这样的问题,但我仍然找不到适合我的问题的解决方案。

我有一个 RGB 图像列表(30.000 总计)。我需要读取每张图像,处理所有三个 RGB 通道,然后将结果保存在内存中(稍后保存在1 大文件中)

我正在尝试使用这样的东西:

import multiprocessing as mp
import random
import numpy as np


# Define an output queue to store result
output = mp.Queue()

# define a example function
def read_and_process_image(id, output):
    result = np.random.randint(256, size=(100, 100, 3)) #fake an image
    output.put(result)

# Setup a list of processes that we want to run
processes = [mp.Process(target=read_and_process_image, args=(id, output)) for id in range(30000)]

# Run processes
for p in processes:
    p.start()

# # Exit the completed processes
# for p in processes:
#     p.join()

# Get process results from the output queue
results = [output.get() for p in processes]

print(results)

此代码使用大量内存。 This answer 解释了这个问题,但我找不到将它应用到我的代码的方法。有什么建议吗?谢谢!

编辑:我也尝试joblib 和Pool 类,但代码不会像我预期的那样使用所有内核(我认为使用普通for 循环没有区别有这两种情况)

【问题讨论】:

  • 您不想启动 30000 个进程。使用池来限制生成的进程数。
  • 如何使用pool来限制进程数(但使用我CPU的所有核心)?我试过了,但代码并没有按照我的意愿使用所有的 CPU。 @ReutSharabani

标签: python memory-leaks threadpool python-multiprocessing


【解决方案1】:

我会使用一个池来限制产生的进程数。我已经根据您的代码编写了一个演示:

import multiprocessing as mp
import os
import numpy as np

# define a example function
def read_and_process_image(_id):
    print("Process %d is working" % os.getpid())
    return np.random.randint(256, size=(100, 100, 3))

# Setup a list of arguments that we want to run the function with
taskargs = [(_id) for _id in range(100)]

# open a pool of processes
pool = mp.Pool(max(1, mp.cpu_count() // 2))
# Run processes
results = pool.map(read_and_process_image, taskargs)

print(results)

我知道没有使用argumnts,但我想你会想看看如何做,以防你确实需要它(另外,我已将id 更改为_id,因为id 是内置的)。

【讨论】:

  • pool = mp.Pool(max1, mp.cpu_count() // 2)) 中的 max1 是多少?顺便说一句,如何添加更多任务参数?因为我真正的read_and_process_image 函数会喜欢read_and_process_image(_id, param_1, param_2)。谢谢!
  • max1 ... 是 max(1 ... 的拼写错误,我已修复。它的目的是至少占用一个处理器,但如果您有更多处理器,则只占用一半的处理器(因为您可能想要一些空闲的时间来做其他事情......)。您可以自己计算要使用多少个处理器。要发送更多参数,只需扩展存储在 taskargs 中的元组。
  • 谢谢!我只是测试您的建议,但它仍然使用大量内存(例如,如果我使用 range(100000) 而不是 range(100),我可以看到我的 RAM 在几秒钟内耗尽)。
  • 这可能是因为这段代码实际上存储了结果。如果您使用Pool.apply_async,您可以选择不存储它们。
  • 在这种情况下(使用Pool.apply_async),我怎样才能找回results的列表?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
  • 1970-01-01
  • 2018-12-18
  • 2016-08-10
  • 2015-06-14
  • 2013-07-01
  • 1970-01-01
相关资源
最近更新 更多