8-6如何使用多进程
一、多进程间的虚拟地址空间是独立的
from multiprocessing import Process 与threading下的Thread使用方法几乎一致
# -*- coding: cp936 -*- from multiprocessing import Process def f_printf(s): print s print "why" def f(): global x x = 5 if __name__ == '__main__': p = Process(target=f_printf, args=('hello',)) p.start() p.join() #上面的用法和多线程是一样的。 #和多线程不一样的是,多线程的虚拟地址空间是不一样的。 x = 1 p = Process(target=f) p.start() print x #此时主线程打印1而子进程里x被设置成5,说明两个进程里的x是独立的,即虚拟地址空间是独立的。
说明:这个测试代码是在pycharm中进行的,在IDLE测试多进程里无法出现现象。
二、进程间通讯
1、队列通讯
>>> from multiprocessing import Queue,Pipe >>> q = Queue() #创建一个队列 >>> q.put(1) #放入队列一个值 >>> q.get() #取队列一个值 1 >>> #注意这里的Queue和线程间通讯时使用的import Queue是不同的模块。 # 这里是进程通讯使用的队列Queue,使用的接口是相同的。
# coding: cp936 from multiprocessing import Queue,Pipe,Process #注意这里的Queue和线程间通讯时使用的import Queue是不同的模块。 # 这里是进程通讯使用的队列Queue,使用的接口是相同的。 import time q = Queue();#创建一个队列 def f(p): #函数阻塞读取队列 print('start') print(p.get()) print('end') if __name__ == '__main__': Process(target = f, args=(q,)).start() print time.asctime() time.sleep(10) print time.asctime() q.put(10) #主进程往队列里发数据时,调用f()函数的进程才会读取到队列的值。
输出结果:
Tue Jan 23 13:57:33 2018
start
Tue Jan 23 13:57:43 2018
10
End
2、管道通讯
>>> c1,c2 = Pipe() #创建管道,生成两端,一端发送时,另一端读取 >>> c1.send('abc') #c1端发送 >>> c2.recv() #c2端读取 'abc' >>> c2.send('xyz') #c2发送时 >>> c1.recv() #c1读取 'xyz' >>>
from multiprocessing import Pipe,Process c1, c2 = Pipe() def f(c): x = 0 while x!=-1: #当函数为-1时不再循环,调用此函数的进程也将结束 x = c.recv() c.send(x*2) if __name__ == "__main__": p = Process(target=f, args=(c2,)) #进程,启动函数f p.start() c1.send(100) print c1.recv() c1.send("400") print c1.recv() c1.send(-1) #发送结束标志 print c1.recv() c1.send(10) #此次发送不再输出,说明p进程已停止了进程 print c1.recv()
输出结果:
200
400400
-2
多进程和多线程执行CPU密集型运算时的比较
计算某一范围的水仙花数
使用多进程方法时(本例使用两个进程),程序启动后很短时间CPU1和CPU2使用率达到100%,说明这两个进程在同时执行
计算共花了15秒的时间。
使用多线程方法时(本例使用两个线程),CPU使用率达不到100%了,系统使用时间也变长了,说明系统在调度,每一个CPU没完全使用以后就被调度了
计算共花了40秒
posted on 2018-05-09 16:10 石中玉smulngy 阅读(120) 评论(0) 编辑 收藏 举报