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执行使用shell命令方法分享
Nov 08 Python
教你用Python写安卓游戏外挂
Jan 11 Python
基于python3实现socket文件传输和校验
Jul 28 Python
详解django中使用定时任务的方法
Sep 27 Python
Python设计模式之策略模式实例详解
Jan 21 Python
将Python文件打包成.EXE可执行文件的方法
Aug 11 Python
python将三维数组展开成二维数组的实现
Nov 30 Python
python3 求约数的实例
Dec 05 Python
关于Pytorch的MNIST数据集的预处理详解
Jan 10 Python
Python如何把多个PDF文件合并代码实例
Feb 13 Python
Python如何根据时间序列数据作图
May 12 Python
详解pycharm配置python解释器的问题
Oct 15 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
PHP4与PHP3中一个不兼容问题的解决方法
2006/10/09 PHP
phpMyAdmin下载、安装和使用入门教程
2007/05/31 PHP
PHP生成随机数的方法实例分析
2015/01/22 PHP
PHP文件上传之多文件上传的实现思路
2016/01/27 PHP
PHP实现字符串的全排列详解
2019/04/24 PHP
原生javascript实现的分页插件pagenav
2014/08/28 Javascript
推荐25个超炫的jQuery网格插件
2014/11/28 Javascript
node.js中的http.response.writeHead方法使用说明
2014/12/14 Javascript
将JavaScript的jQuery库中表单转化为JSON对象的方法
2015/11/17 Javascript
Bootstrap按钮组件详解
2016/04/26 Javascript
利用jquery实现验证输入的是否是数字、小数,包含保留几位小数
2016/12/07 Javascript
JS获取多维数组中相同键的值实现方法示例
2017/01/06 Javascript
javascript过滤数组重复元素的实现方法
2017/05/03 Javascript
vue 指定组件缓存实例详解
2018/04/01 Javascript
antd日期选择器禁止选择当天之前的时间操作
2020/10/29 Javascript
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
Python合并字符串的3种方法
2015/05/21 Python
Python使用sftp实现上传和下载功能(实例代码)
2017/03/14 Python
用python的requests第三方模块抓取王者荣耀所有英雄的皮肤实例
2017/12/14 Python
Python使用字典实现的简单记事本功能示例
2019/08/15 Python
python的help函数如何使用
2020/06/11 Python
英语专业应届生求职信范文
2013/11/15 职场文书
初三化学教学反思
2014/01/23 职场文书
五好党支部事迹材料
2014/02/06 职场文书
体育教师自我鉴定
2014/02/12 职场文书
学习“七一”讲话精神体会
2014/07/08 职场文书
学校领导班子对照检查材料
2014/09/24 职场文书
党员查摆四风问题思想汇报
2014/10/25 职场文书
群众路线教育实践活动学习笔记
2014/11/05 职场文书
2014年司机工作总结
2014/11/21 职场文书
五好家庭事迹材料
2014/12/20 职场文书
文艺部部长竞选稿
2015/11/21 职场文书
解除租赁合同协议书
2016/03/21 职场文书
MySQL下使用Inplace和Online方式创建索引的教程
2021/05/26 MySQL
在Java中Collection的一些常用方法总结
2021/06/13 Java/Android
Mongodb 迁移数据块的流程介绍分析
2022/04/18 MongoDB