Python培训
400-996-5531
多进程存在的意义就是为了让我们的电脑在同一时间做更多的事情,比如你可以一边听歌一边更新博客。
咱们先普及一下操作系统是如何实现多进程操作的。在linux/unix 系统中提供一个fork()指令,fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。多年前流行的linux指令,fork炸弹的原理就是让操作系统疯狂的创建子进程以耗尽系统资源,达到系统死机的效果。
multiprocessing模块
multiprocessing模块是python自带的多进程操作模块。python编写,跨平台。看个小例子。
from multiprocessing import Processimport osdef run_proc(name): print '我的子进程 %s (%s)...' % (name, os.getpid())if __name__=='__main__': print '我是父进程 %s.' % os.getpid() p = Process(target=run_proc, args=('test',)) print 'start.' p.start() p.join() print 'end.'#执行我是父进程 4908.start.我的子进程 test (9744)...end.这个小例子 就创建了一个子进程,join()方法可以等待子进程结束后父进程再继续往下运行。
Pool方法
Pool方法,用于批量创建大量子进程的情况,看实例
#!/usr/bin/env python#-*- coding:utf-8 -*-__author__ = 'weihaoxuan'from multiprocessing import Poolimport os, timedef long_time_task(name): print '%s我是子进程 %s (%s)...' % (time.time(),name, os.getpid()) time.sleep(1)if __name__=='__main__': print '我是父进程 %s.' % os.getpid() p = Pool() for i in range(5): p.apply_async(long_time_task, args=(i,)) print '进程创建完成' p.close() p.join() print 'end'#执行我是父进程 11468.进程创建完成1508919194.76我是子进程 0 (12752)...1508919194.76我是子进程 1 (15124)...1508919194.77我是子进程 2 (212)...1508919194.77我是子进程 3 (8364)...1508919195.76我是子进程 4 (12752)...end#可以看到,几乎是在同一时间我们创建了5个子进程。#同样的 这里的p.join() 方法也会等待所有子进程结束后,才会继续执行父进程。#close()方法表示 本次批量创建结束,调用close()之后就不能继续添加新的子进程了
Pool() 方法可以带上参数,比如Pool(4),意思就是同一时间只能有4个子进程同时执行,我们把上面的代码稍加修改,看一下效果
#!/usr/bin/env python#-*- coding:utf-8 -*-from multiprocessing import Poolimport os, timedef long_time_task(name): print '%s我是子进程 %s (%s)...' % (time.time(),name, os.getpid()) time.sleep(1)if __name__=='__main__': print '我是父进程 %s.' % os.getpid() p = Pool(2) ###这里 for i in range(5): p.apply_async(long_time_task, args=(i,)) print '进程创建完成' p.close() p.join() print 'end'#执行我是父进程 10048.进程创建完成1508919484.57我是子进程 0 (16924)...1508919484.57我是子进程 1 (11440)...1508919485.57我是子进程 2 (16924)...1508919485.57我是子进程 3 (11440)...1508919486.57我是子进程 4 (16924)...end#看到没 同一时间只有2个进程在运行。
进程间通信
或许你曾听说过,进程之间是不可以直接通信和传递数据的。如果这样的话,我们的程序岂不是被限制住了?当然不,进程之间肯定是需要通信的。但是要借助一些第三方通道,例如mq
Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
这里我们使用Queue来演示,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据,一个简单的生产者消费者模型
#!/usr/bin/env python#-*- coding:utf-8 -*-__author__ = 'weihaoxuan'from multiprocessing import Process, Queueimport os, time, randomdef PUT(q): for value in ['1', '2', '3']: print '存放 %s 到队列里.' % value q.put(value) time.sleep(random.random())def GET(q): while True: value = q.get(True) print '从队列里取出了 %s.' % valueif __name__=='__main__': q = Queue() pw = Process(target=PUT, args=(q,)) pr = Process(target=GET, args=(q,)) pw.start() pr.start() pw.join() print 'kill GET' pr.terminate()#这里我们创建了两个子进程,一个PUT,一个GET,分别启动两个子进程,pr.terminate()的意思是 强行结束GET进程。因为GET是个死循环 。#执行存放 1 到队列里.从队列里取出了 1.存放 2 到队列里.从队列里取出了 2.存放 3 到队列里.从队列里取出了 3.kill GET#通过这样的转换,完成了进程间的通讯。
总结
python自带的multiprocessing包可以完美的实现多进程代码的编写,大大提高了我们程序的执行效率和编码方面的多样性。这里需要注意一下,本文出于演示的关系,在多进程间通信中使用了Queue来实现。在实际生产环境中,应该用更出色的第三方队列如rabbitmq。或者redis 等来代替。已获得更好的性能。
题外话.虽然多进程大大提高了程序的运行效率,但是在编程的时候还是要充分考虑到操作系统性能,切记不要一次性开太多进程,耗尽系统资源导致宕机等故障发生。
好啦 关于多进程,就讲到这里啦。
本文内容转载自网络,本着分享与传播的原则,版权归原作者所有,如有侵权请联系我们进行删除!
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved