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 11 Python
Python入门_学会创建并调用函数的方法
May 16 Python
python 2.7.14安装图文教程
Apr 08 Python
Python实现统计给定列表中指定数字出现次数的方法
Apr 11 Python
Python绘制3D图形
May 03 Python
Python Cookie 读取和保存方法
Dec 28 Python
基于python的selenium两种文件上传操作实现详解
Sep 19 Python
Python pygame绘制文字制作滚动文字过程解析
Dec 12 Python
Python如何将将模块分割成多个文件
Aug 04 Python
python解压zip包中文乱码解决方法
Nov 27 Python
python 检测图片是否有马赛克
Dec 01 Python
Python读取文件夹下的所有文件实例代码
Apr 02 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 无法加载mysql的module的时候的配置的解决方案引发的思考
2012/01/27 PHP
PHP+Redis 消息队列 实现高并发下注册人数统计的实例
2018/01/29 PHP
基于thinkphp6.0的success、error实现方法
2019/11/05 PHP
js/jquery解析json和数组格式的方法详解
2014/01/09 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
JS ES6多行字符串与连接字符串的表示方法
2017/04/26 Javascript
一次围绕setTimeout的前端面试经验分享
2017/06/15 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
vue.js如何将echarts封装为组件一键使用详解
2017/10/10 Javascript
swiper在vue项目中loop循环轮播失效的解决方法
2018/09/15 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
[02:12]2019完美世界全国高校联赛(春季赛)报名开启
2019/03/01 DOTA
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
python unittest实现api自动化测试
2018/04/04 Python
python高斯分布概率密度函数的使用详解
2019/07/10 Python
解决django服务器重启端口被占用的问题
2019/07/26 Python
Pytorch 保存模型生成图片方式
2020/01/10 Python
Python实现CNN的多通道输入实例
2020/01/17 Python
Python requests模块cookie实例解析
2020/04/14 Python
纯css3使用vw和vh实现自适应的方法
2018/02/09 HTML / CSS
吉列剃须刀美国官网:Gillette美国
2018/07/13 全球购物
维多利亚的秘密阿联酋官网:Victoria’s Secret阿联酋
2019/12/07 全球购物
Theflamel意大利:女士奢华服装、鞋子和配件
2020/01/11 全球购物
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
麦当劳辞职信范文
2014/01/18 职场文书
文秘档案管理岗位职责
2014/03/06 职场文书
学校创先争优活动总结
2014/08/28 职场文书
公民授权委托书
2014/10/15 职场文书
吃空饷专项整治方案
2014/10/27 职场文书
怎样写离婚协议书
2015/01/26 职场文书
音乐研修感悟
2015/11/18 职场文书
什么是检讨书?检讨书的格式及范文
2019/11/05 职场文书
python实现三次密码验证的示例
2021/04/29 Python
mysql在项目中怎么选事务隔离级别
2021/05/25 MySQL
SQLServer之常用函数总结详解
2021/08/30 SQL Server