【python】多进程中的内存复制
来源:互联网 发布:mac ntfs读写插件破解 编辑:程序博客网 时间:2024/05/19 19:41
比较好奇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结果:
(四个子进程)
(父进程及四个子进程)
由上两张图可以看出父进程及子进程都各自占用了1.4G左右的内存空间。而大部分内存空间存储的是读数据lines,所以这样的内存开销太浪费。
优化计划
计划1:通过内存共享来减少内存的开销。
关于内存共享的资料可参考:http://www.360doc.com/content/11/0408/23/4910_108289025.shtml
计划2: 主进程不再读取文件对象,交给每个工作进程去读取文件中的相应部分。
改进代码:
def line_count(file_name): count = -1 #让空文件的行号显示0 for count,line in enumerate(open(file_name)): pass #enumerate格式化成了元组,count就是行号,因为从0开始要+1 return count+1def parse_lines(args): f = open(args[0] , 'r') lines = f.readlines()[args[1]:args[2]] #read some lines f.close() #workingdef 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中使用多进程复制文件
- Python 实现多进程复制文件
- python多进程中的进程池pool
- python中的多进程处理
- Python 中的 Subprocess 多进程
- python中的多进程处理
- Python中的多进程处理
- Python中的多进程学习
- 【Python】Python中的多线程与多进程
- python 多进程 内存 copy-on-write
- 进程中的共享内存
- Python中的GIL、多进程和多线程
- 关于python中的多进程模块multiprocessing
- Python中的异步与多进程
- 为何安卓机器中在设置中看到的RAM比实际小
- Mybatis 配置 lazyLoadingEnabled=true 的错误
- c++基础学习网址
- Android 软键盘盖住输入框的问题
- 使用单例模式实现自己的HttpClient工具类
- 【python】多进程中的内存复制
- Silverlight DataGri列模版,行头图标模版,列头模版,多重表头,,编辑模版,样式
- android-screen-monitor windows下android手机与电脑同步显示
- Request.params、Request、Request.querystring、Request.Form 具体区别!
- 为何在设置-安全中选择图案解锁后,《电源按钮即时锁定》按钮取消选中无效
- 页面缓存以及ubuntu下apahce的httpd.conf文件
- adb进入android文件系统的基本操作
- JAVA_String类及StringBuffer类
- 什么是B+、U+,使用Ultraiso技术