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除法运算小技巧
Apr 05 Python
Python中SOAP项目的介绍及其在web开发中的应用
Apr 14 Python
在Python的Flask框架中实现全文搜索功能
Apr 20 Python
python3+PyQt5泛型委托详解
Apr 24 Python
python XlsxWriter模块创建aexcel表格的实例讲解
May 03 Python
Python3.6使用tesseract-ocr的正确方法
Oct 17 Python
virtualenv 指定 python 解释器的版本方法
Oct 25 Python
Pyinstaller打包.py生成.exe的方法和报错总结
Apr 02 Python
Python requests获取网页常用方法解析
Feb 20 Python
python中Ansible模块的Playbook的具体使用
May 28 Python
Python如何操作docker redis过程解析
Aug 10 Python
Ubuntu配置Pytorch on Graph (PoG)环境过程图解
Nov 19 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 数组教程 定义数组
2009/10/23 PHP
PHP中的Streams详细介绍
2014/11/12 PHP
php判断当前操作系统类型
2015/10/28 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
用jquery实现下拉菜单效果的代码
2010/07/25 Javascript
url地址自动加#号问题说明
2010/08/21 Javascript
jquery判断字符输入个数(数字英文长度记为1,中文记为2,超过长度自动截取)
2010/10/15 Javascript
jQuery学习基础知识小结
2010/11/25 Javascript
jquery+json实现数据列表分页示例代码
2013/11/15 Javascript
JS实现可调整倒计时间代码分享
2015/08/18 Javascript
javascript高级选择器querySelector和querySelectorAll全面解析
2016/04/07 Javascript
js运动事件函数详解
2016/10/21 Javascript
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
收集前端面试题之url、href、src
2018/03/22 Javascript
微信小程序与后台PHP交互的方法实例分析
2018/12/10 Javascript
layui多iframe页面控制定时器运行的方法
2019/09/05 Javascript
js实现列表按字母排序
2020/08/11 Javascript
JS实现超级好看的鼠标小尾巴特效
2020/12/01 Javascript
Python实现windows下模拟按键和鼠标点击的方法
2015/03/13 Python
django 发送手机验证码的示例代码
2018/04/25 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
2019/07/05 Python
Python调用Windows API函数编写录音机和音乐播放器功能
2020/01/05 Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
2020/03/13 Python
Cult Gaia官网:美国生活方式品牌
2019/08/16 全球购物
写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)
2014/09/05 面试题
皮肤科医师岗位职责
2013/12/04 职场文书
医学生职业规划范文
2014/01/05 职场文书
化学工程专业求职信
2014/08/10 职场文书
基层党建工作汇报材料
2014/08/15 职场文书
代办社保委托书范文
2014/10/06 职场文书
办公室行政主管岗位职责
2015/04/09 职场文书
护士旷工检讨书
2015/08/15 职场文书
使用CSS实现百叶窗效果示例代码
2023/05/07 HTML / CSS