我的代码需要一些帮助,我正在尝试使用池来运行我的列表中的一些函数。
这是一个包含大量数据的文件。比如 71GB 的文本。
我正在尝试尽快越线。 但是由于某种原因,在运行过程中,我因内存不足而被杀死
我认为这是因为我的 pool.close 和 pool.join 在我的代码末尾。
但我不知道如何修复它以避免内存泄漏。我认为我的过程永远不会停止并保存数据。
注意:api.delete_object(item) 返回大量数据。也许它以某种方式卡在内存中?
这是我的代码:
import pandas as pd
import boto3
from multiprocessing.pool import ThreadPool as Pool
pool_size = 8 # my "parallelness"
def worker(item):
try:
result = api.delete_object(item)
except:
print('error with item')
pool = Pool(pool_size)
i=0
for chunk in pd.read_csv("/folder/files_to_delete",chunksize=1000,header=None):
i+=1000
for ind in chunk.index:
if "something.txt" not in chunk[0][ind]:
pool.apply_async(worker, (chunk[0][ind],))
print("{}".format(i), end='\r')
pool.close()
pool.join()
答案 0 :(得分:0)
尽管您使用 multiprocessing
标记了您的问题,但您使用的是多线程。但在我看来,使用多处理可能会更好,因为我不清楚使用线程执行 api.delete_object(item)
可以实现多少“并行”。
无论如何,您可以尝试重新排列代码以使用函数 imap_unordered
,然后迭代它返回的 iterable。虽然您的工作函数 worker
的返回值不是特别有趣(发布的工作函数仅返回 None
,但这也许是一种简化),检索这些值应该释放正在曾经拿着它们。
import pandas as pd
import boto3
from multiprocessing.pool import ThreadPool as Pool
def generate_arguments():
i = 0
with pd.read_csv("/folder/files_to_delete",chunksize=1000,header=None) as rdr:
for chunk in rdr:
i += 1000
for ind in chunk.index:
if "something.txt" not in chunk[0][ind]:
yield chunk[0][ind]
print("{}".format(i), end='\r')
def worker(item):
try:
result = api.delete_object(item)
except:
print('error with item')
def main():
pool_size = 8 # my "parallelness"
pool = Pool(pool_size)
results = pool.imap_unordered(worker, generate_arguments())
# You can iterate results to get return values, which are None, from worker function:
for result in results:
# result is return value from worker
pass
pool.close()
pool.join()
if __name__ == '__main__':
main()
如果您确实切换到多处理,您应该在调用 imap_unordered
时指定一个 chunksize 参数。我建议您估算将提交的任务数量并除以 4 * 池大小,并将结果用作该值。例如,如果您估计将提交 200,000 个任务并且池大小为 8,则使用 chunksize 值 200_000 / (4 * 8) = 6250
。
请注意,imap_unordered
可以以任意顺序返回结果,但比 imap
更有效。如果您实际上是从 worker
返回的不是 None
并且需要结果按照任务提交的顺序,那么使用方法 imap
或让 imap_unordered
额外返回其传递参数。