python多进程中的内存复制(实例讲解)


Posted in Python onJanuary 05, 2018

比较好奇python对于多进程中copy on write机制的实际使用情况。目前从实验结果来看,python 使用multiprocessing来创建多进程时,无论数据是否不会被更改,子进程都会复制父进程的状态(内存空间数据等)。所以如果主进程耗的资源较多时,不小心就会造成不必要的大量的内存复制,从而可能导致内存爆满的情况。

示例

举个例子,假设主进程读取了一个大文件对象的所有行,然后通过multiprocessing创建工作进程,并循环地将每一行数据交给工作进程来处理:

def parse_lines(args):
 #working
 ...
def main_logic():
 f = open(filename , 'r')
 lines = f.readlines()
 f.close()
 pool = multiprocessing.Pool(processes==4)
 rel = pool.map(parse_lines , itertools.izip(lines , itertools.repeat(second_args)) , int(len(lines)/4))
 pool.close()
 pool.join()

以下是top及ps结果:

python多进程中的内存复制(实例讲解)

(四个子进程)

python多进程中的内存复制(实例讲解)

(父进程及四个子进程)

由上两张图可以看出父进程及子进程都各自占用了1.4G左右的内存空间。而大部分内存空间存储的是读数据lines,所以这样的内存开销太浪费。

优化计划

1: 在主进程初期未导入大量的py库之前创建进程,或者动态加载py库。

2:通过内存共享来减少内存的开销。

3: 主进程不再读取文件对象,交给每个工作进程去读取文件中的相应部分。

改进代码:

def line_count(file_name):
 count = -1 #让空文件的行号显示0
 for count,line in enumerate(open(file_name)): pass
 #enumerate格式化成了元组,count就是行号,因为从0开始要+1
 return count+1
def parse_lines(args):
 f = open(args[0] , 'r')
 lines = f.readlines()[args[1]:args[2]] #read some lines
 f.close() 
 #working
def main_logic(filename,process_num):
 line_count = line_count(filename)
 avg_len = int(line_count/process_num)
 left_cnt = line_count%process_num;
 pool = multiprocessing.Pool(processes=process_num)
 for i in xrange(0,process_num):
  ext_cnt = (i>=process_num-1 and [left_cnt] or [0])[0]
  st_line = i*avg_len
  pool.apply_async(parse_lines, ((filename, st_line, st_line+avg_len+ext_cnt),)) #指定进程读某几行数据
 pool.close()
 pool.join()

再次用top或者ps来查看进程的内存使用情况:

python多进程中的内存复制(实例讲解)

(四个子进程)

python多进程中的内存复制(实例讲解)

(父进程及四个子进程)

小结

对比两次的内存使用情况,改进代码后父进程及子进程所占用的内存明显减少;所有内存占用相当于原来的一半,这就是减少内存复制的效果。

关于内存使用这方面还有不少优化方法和空间,稍后继续研究。

以上这篇python多进程中的内存复制(实例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 参数列表中的self 显式不等于冗余
Dec 01 Python
通过C++学习Python
Jan 20 Python
解读! Python在人工智能中的作用
Nov 14 Python
使用python对文件中的数值进行累加的实例
Nov 28 Python
python tkinter实现屏保程序
Jul 30 Python
Python的Lambda函数用法详解
Sep 03 Python
Python基于Dlib的人脸识别系统的实现
Feb 26 Python
Python3将ipa包中的文件按大小排序
Apr 17 Python
python中线程和进程有何区别
Jun 17 Python
详解Python中Pyyaml模块的使用
Oct 08 Python
python 实现端口扫描工具
Dec 18 Python
利用Pycharm连接服务器的全过程记录
Jul 01 Python
使用python和Django完成博客数据库的迁移方法
Jan 05 #Python
Python3多线程爬虫实例讲解代码
Jan 05 #Python
python编写微信远程控制电脑的程序
Jan 05 #Python
使用python爬虫实现网络股票信息爬取的demo
Jan 05 #Python
简单实现python收发邮件功能
Jan 05 #Python
5款非常棒的Python工具
Jan 05 #Python
Python基于列表模拟堆栈和队列功能示例
Jan 05 #Python
You might like
PHP采集静态页面并把页面css,img,js保存的方法
2014/12/23 PHP
PHP使用redis实现统计缓存mysql压力的方法
2015/11/14 PHP
php微信开发之自定义菜单完整流程
2016/10/08 PHP
PHP实现的链式队列结构示例
2017/09/15 PHP
javascript下查找父节点的简单方法
2007/08/13 Javascript
定义select的边框颜色
2008/04/28 Javascript
初学Javascript的一些总结
2008/11/03 Javascript
基于jquery自定义图片热区效果
2012/07/21 Javascript
JavaScript基础篇之变量作用域、传值、传址的简单介绍与实例
2013/06/29 Javascript
JavaScript运行过程中的“预编译阶段”和“执行阶段”
2015/12/16 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
JavaScript实现经典排序算法之插入排序
2016/12/28 Javascript
浅谈关于JS下大批量异步任务按顺序执行解决方案一点思考
2019/01/08 Javascript
Weex开发之地图篇的具体使用
2019/10/16 Javascript
构建一个JavaScript插件系统
2020/10/20 Javascript
Python中模块string.py详解
2017/03/12 Python
Python3自动签到 定时任务 判断节假日的实例
2018/11/13 Python
pandas 将索引值相加的方法
2018/11/15 Python
Django实现学员管理系统
2019/02/26 Python
Django实现将一个字典传到前端显示出来
2020/04/03 Python
python中wx模块的具体使用方法
2020/05/15 Python
Python实现读取并写入Excel文件过程解析
2020/05/27 Python
Python基于yaml文件配置logging日志过程解析
2020/06/23 Python
大学生就业策划书范文
2014/04/04 职场文书
教书育人演讲稿
2014/09/11 职场文书
山东省召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
地方白酒代理协议书
2014/10/25 职场文书
大学生创业事迹材料
2014/12/30 职场文书
杜甫草堂导游词
2015/02/03 职场文书
评职称个人总结
2015/03/05 职场文书
鉴史问廉观后感
2015/06/10 职场文书
施工安全协议书
2016/03/22 职场文书
个人工作总结(管理人员)范文
2019/08/13 职场文书
PHP 技巧 * SVG 保存为图片(分享图生成)
2021/04/02 PHP
手写实现JS中的new
2021/11/07 Javascript
webpack介绍使用配置教程详解webpack介绍和使用
2022/06/25 Javascript