python multiprocessing.pool.apply_async 占用内存多 解决方法

摘要:
多重处理工具。apply_Async可以执行并行进程,但它会先将所有进程读入列表。对于少数进程来说,这是没有问题的。但是,如果有大量的进程,例如100万和1000万,并且进程无法快速完成,那么内存将被占用很多,甚至可能会爆裂。那么如何限制内存占用。在线搜索并找到解决方案:检查池_缓存的长度。如果它超过一定长度,最终进入池的进程将等待,

multiprocessing.pool.apply_async 可以执行并行的进程,但是会将所有进程先读入列表,对于不是很多数量的进程来说没有问题,但是如果进程数量很多,比如100万条,1000万条,而进程不能很快完成,内存就会占用很多,甚至挤爆内存。那么如何限制内存的占有量呢。网上查询,找到一种解决方法:可以检测pool._cache的长度,如果超过一定的长度,就让最后进入pool中的进程等待,等这个进程结束,再读入一定长度的进程,以达到减少内存占有的目的。

from multiprocessing import Pool
import time

def downloadGif(arg):
    print(arg[0])
    time.sleep(1)

def downloading_over(arg):
    pass

def foo(num):
    for i in range(num,1000001):
        pic_info=[]
        pic_info.append(str(i)+'gif')

        txt_info=[]
        txt_info.append(str(i)+'txt')
        yield pic_info,txt_info

if __name__ == '__main__':
    pool = Pool(processes=5)    # set the processes max number
    count=1
    for download in foo(2):
        pool.apply_async(func=downloadGif, args=(download[0],),callback=downloading_over)
        last=pool.apply_async(func=downloadGif, args=(download[1],),callback=downloading_over)

        count=count+1
        print(count)

        if len(pool._cache) > 1e3:
            print("waiting for cache to clear...")
            last.wait()

#1e3,500条,占有内存10M
#1e4,5000条,占有内存20M
#1e5,50000条,占有内存200M
#1e6,500000条,占有内存2000M

    pool.close()
    pool.join()

核心代码:

        if len(pool._cache) > 1e3:
            print("waiting for cache to clear...")
            last.wait()

last 是 AsyncResult的实例,是pool的返回值

https://docs.python.org/3/library/multiprocessing.html

class multiprocessing.pool.AsyncResult

The class of the result returned by Pool.apply_async() and Pool.map_async().

get([timeout])

Return the result when it arrives. If timeout is not None and the result does not arrive within timeout seconds then multiprocessing.TimeoutError is raised. If the remote call raised an exception then that exception will be reraised by get().

wait([timeout])

Wait until the result is available or until timeout seconds pass.

ready()

Return whether the call has completed.

successful()

Return whether the call completed without raising an exception. Will raise ValueError if the result is not ready.

本文参考下面链接回答:

https://stackoverflow.com/questions/18414020/memory-usage-keep-growing-with-pythons-multiprocessing-pool

免责声明:文章转载自《python multiprocessing.pool.apply_async 占用内存多 解决方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【PMP】项目生命周期和开发生命周期用XPath定位Web页面元素时,如何快速验证XPath语句是否正确?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

dmidecode的Python解析

#!/usr/bin/env python # -*- coding: utf-8 -*- """ 解析dmidecode命令输出结果,返回JSON格式数据 测试服务器Dell VMware虚拟机 测试系统为CentOS 6.x 7.x Python版本为Python3.6 原版参考的是 https://pypi.org/project/dm...

Python基础-5

目录 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 hashlib re正则表达式 模块分为三种: 自定义模块 内置标准模块(又称标准库) 开源模块 自定义模块 和开源模块的使用参考 http://www.cnblogs.com/wupe...

模块与包的导入

1.模块什么是模块: #常见的场景:一个模块就是一个包含了python定义和声明的文件(文件名就是模块名字加上.py的后缀),模块可以被导入使用。 #但其实import加载的模块分为四个通用类别:  使用python编写的.py文件 已被编译为共享库或DLL的C或C++扩展 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该...

Ubuntu 16.04 安装 python3.8

Ubuntu 16.04  amd64 (64bit)(纯净版) 自带python2.7和python3.5 执行"whereis python"查看当前安装的python [root@root ~]# whereis python python: /usr/bin/python2.7 /usr/bin/python /usr/lib/python2.7...

数据看板superset在Windows环境下安装

@https://www.cnblogs.com/calmzeal/archive/2017/08/14/7359144.html 以下是我的安装版本与安装步骤: 1. 安装Python 3.7 ,python-3.7.1-amd64.exe 检查:CMD下 分别运行python -V 和 pip-V。如果找不到命令,则需要添加python的安装目录到pa...

Python项目读取配置的几种方式

1. 将配置写在Python文件中 配置文件(config.py 或 settings.py) 通常放置在程序源代码的目录,方便引用 配置文件 # settings.py class Config(object): DEBUG = False TESTING = False DATABASE_URI = 'sqlite://:memo...