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 02 Python
Python中的rfind()方法使用详解
May 19 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
Pyspider中给爬虫伪造随机请求头的实例
May 07 Python
浅析python中的迭代与迭代对象
Oct 08 Python
python三大神器之fabric使用教程
Jun 10 Python
Django模型序列化返回自然主键值示例代码
Jun 12 Python
python实现日志按天分割
Jul 22 Python
Django CBV类的用法详解
Jul 26 Python
python 字符串常用函数详解
Sep 11 Python
Python中itertools的用法详解
Feb 07 Python
python numpy生成等差数列、等比数列的实例
Feb 25 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
mysql 搜索之简单应用
2007/04/27 PHP
php面向对象全攻略 (一) 面向对象基础知识
2009/09/30 PHP
解析php中如何调用用户自定义函数
2013/08/06 PHP
使用Zttp简化Guzzle 调用
2017/07/02 PHP
thinkPHP框架实现类似java过滤器的简单方法示例
2018/09/05 PHP
在PHP中实现使用Guzzle执行POST和GET请求
2019/10/15 PHP
jquery 自定义容器下雨效果可将下雨图标改为其他
2014/04/23 Javascript
JavaScript对数字的判断与处理实例分析
2015/02/02 Javascript
BootStrap Table 分页后重新搜索问题的解决办法
2016/08/08 Javascript
ES6中Proxy代理用法实例浅析
2017/04/06 Javascript
Vue.js中组件中的slot实例详解
2017/07/17 Javascript
jQuery实现的简单对话框拖动功能示例
2018/06/05 jQuery
Vue多系统切换实现方案
2018/06/05 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
2019/12/10 Javascript
JS实现表单中点击小眼睛显示隐藏密码框中的密码
2020/04/13 Javascript
JQuery获得内容和属性方法解析
2020/05/30 jQuery
[02:42]决战东方!DOTA2亚洲邀请赛重启荣耀之争
2017/03/17 DOTA
[01:07:15]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第二场 1月25日
2021/03/11 DOTA
对Tensorflow中的矩阵运算函数详解
2018/07/27 Python
浅谈Python编程中3个常用的数据结构和算法
2019/04/30 Python
详解python内置常用高阶函数(列出了5个常用的)
2020/02/21 Python
Python常用编译器原理及特点解析
2020/03/23 Python
CSS3实现的闪烁跳跃进度条示例(附源码)
2013/08/19 HTML / CSS
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
俄罗斯在线大型超市:ТутПросто
2021/01/08 全球购物
杭州信雅达系统.NET工程师面试试题
2015/02/08 面试题
优秀社区干部事迹材料
2014/02/03 职场文书
超市活动计划书
2014/04/24 职场文书
商务日语专业的自荐信
2014/05/23 职场文书
市场营销专业求职信
2014/06/17 职场文书
建筑节能汇报材料
2014/08/22 职场文书
小学校园广播稿集锦
2014/10/04 职场文书
全国法制宣传日活动总结2014
2014/11/01 职场文书
高三数学复习备考教学反思
2016/02/18 职场文书
承诺书的内容有哪些,怎么写?
2019/06/21 职场文书
JAVA 线程池(池化技术)的实现原理
2022/04/28 Java/Android