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求解平方根的方法
Mar 11 Python
谈谈Python进行验证码识别的一些想法
Jan 25 Python
浅谈python类属性的访问、设置和删除方法
Jul 25 Python
python线程池(threadpool)模块使用笔记详解
Nov 17 Python
python二维列表一维列表的互相转换实例
Jul 02 Python
Python实现基于POS算法的区块链
Aug 07 Python
Python实现计算对象的内存大小示例
Jul 10 Python
TensorFlow内存管理bfc算法实例
Feb 03 Python
python 装饰器功能与用法案例详解
Mar 06 Python
python制作图形界面的2048游戏, 基于tkinter
Apr 06 Python
Django rest framework如何自定义用户表
Jun 09 Python
使用pd.merge表连接出现多余行的问题解决
Jun 16 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实现ping
2006/10/09 PHP
PHP冒泡排序算法代码详细解读
2011/07/17 PHP
Codeigniter中集成smarty和adodb的方法
2016/03/04 PHP
理解JavaScript中的事件
2006/09/23 Javascript
通过Jquery遍历Json的两种数据结构的实现代码
2011/01/19 Javascript
更优雅的事件触发兼容
2011/10/24 Javascript
js 中将多个逗号替换为一个逗号的代码
2014/06/07 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
Bootstrap页面布局基础知识全面解析
2016/06/13 Javascript
很棒的js选项卡切换效果
2016/07/15 Javascript
js改变html的原有内容实现方法
2016/10/05 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
jQuery获取Table某列的值(推荐)
2017/03/03 Javascript
JavaScript正则表达式的贪婪匹配和非贪婪匹配
2017/09/05 Javascript
JS实现的简单表单验证功能示例
2017/10/13 Javascript
详解Vue用自定义指令完成一个下拉菜单(select组件)
2017/10/31 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
Vue仿百度搜索功能
2020/12/28 Vue.js
[47:20]DAC2018 4.4 淘汰赛 Optic vs Mineski 第一场
2018/04/05 DOTA
使用Python进行二进制文件读写的简单方法(推荐)
2016/09/12 Python
python批量识别图片指定区域文字内容
2019/04/30 Python
pymysql的简单封装代码实例
2020/01/08 Python
pytorch 实现将自己的图片数据处理成可以训练的图片类型
2020/01/08 Python
浅谈django框架集成swagger以及自定义参数问题
2020/07/07 Python
香港最大的洋酒零售连锁店:屈臣氏酒窖(Watson’s Wine)
2018/12/10 全球购物
伦敦鲜花递送:Flower Station
2021/02/03 全球购物
mysql有关权限的表都有哪几个
2015/04/22 面试题
团员的自我评价
2013/12/01 职场文书
奶茶店创业计划书范文
2014/01/17 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
2014全国两会学习心得体会1000字
2014/03/10 职场文书
教育系统干部作风整顿心得体会
2014/09/09 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
2015应届毕业生自荐信范文
2015/03/05 职场文书
2016年小学教师政治学习心得体会
2016/01/23 职场文书
python通过opencv调用摄像头操作实例分析
2021/06/07 Python