比较好奇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: 在主进程初期未导入大量的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,多进程,内存,复制
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。