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中的多重继承实例讲解
Sep 28 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
Sep 21 Python
使用python实现个性化词云的方法
Jun 16 Python
Python如何快速实现分布式任务
Jul 06 Python
利用标准库fractions模块让Python支持分数类型的方法详解
Aug 11 Python
python3 pillow生成简单验证码图片的示例
Sep 19 Python
Python应用库大全总结
May 30 Python
Python合并同一个文件夹下所有PDF文件的方法
Mar 11 Python
ipython和python区别详解
Jun 26 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
Aug 02 Python
TensorFlow设置日志级别的几种方式小结
Feb 04 Python
python程序实现BTC(比特币)挖矿的完整代码
Jan 20 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
咖啡知识大全
2021/03/03 新手入门
深入php 正则表达式的学习探讨
2013/06/06 PHP
PHP使用redis消息队列发布微博的方法示例
2017/06/22 PHP
php 二维数组快速排序算法的实现代码
2017/10/17 PHP
PHP7 错误处理机制修改
2021/03/09 PHP
js 文件引入实现代码
2010/04/23 Javascript
JS 自定义函数缺省值的设置方法
2010/05/05 Javascript
JavaScript 变量作用域分析
2011/07/04 Javascript
编程语言JavaScript简介
2014/10/16 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
jQuery使用empty()方法删除元素及其所有子元素的方法
2015/03/26 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
jQuery拖动布局其结果保存到数据库
2015/10/09 Javascript
Javascript模仿淘宝信用评价实例(附源码)
2015/11/26 Javascript
Bootstrap每天必学之面板
2015/11/30 Javascript
js实现一键复制功能
2017/03/16 Javascript
xmlplus组件设计系列之路由(ViewStack)(7)
2017/05/02 Javascript
Vue实现的父组件向子组件传值功能示例
2019/01/19 Javascript
国内常用的js类库大全(CDN公共库)
2020/06/24 Javascript
[01:03:41]完美世界DOTA2联赛PWL S3 DLG vs Phoenix 第一场 12.17
2020/12/19 DOTA
python实现的生成随机迷宫算法核心代码分享(含游戏完整代码)
2014/07/11 Python
Python基于列表模拟堆栈和队列功能示例
2018/01/05 Python
python requests爬取高德地图数据的实例
2018/11/10 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
2019/05/15 Python
Python Pandas 获取列匹配特定值的行的索引问题
2019/07/01 Python
python删除指定列或多列单个或多个内容实例
2020/06/28 Python
一套英文Java笔试题面试题
2016/04/21 面试题
出国导师推荐信
2014/01/16 职场文书
英语生日邀请函
2014/01/23 职场文书
艺术学院毕业生求职信
2014/07/09 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
雨中的树观后感
2015/06/03 职场文书
2015秋季开学典礼致辞
2015/07/16 职场文书
2015年秋季运动会加油稿
2015/07/22 职场文书
详解PHP Swoole与TCP三次握手
2021/05/27 PHP
python实现剪贴板的操作
2021/07/01 Python