1.子进程执行
Pipe方法返回(conn1,conn2)代表一个管道的两个端,Pipe方法有duplex参数,如果duplex参数为TRUE(默认值),那么这个管道是双全工模式,也就是说conn1和conn2均可收发。若duplex为False,conn1只负责接收消息,conn2只负责发送消息,send和recv方法分别是发送和接收消息的方法
创建子进程时,只需传入一个执行函数和函数的参数,即可完成一个Process实例的创建,start()启动进程,join()方法实现进程间的同步
import os
from multiprocessing import Process
def run_proc(name):
#getpid是获得当前进程的进程号
print 'Clild process %s (%s) Running...'%(name,os.getpid())
if __name__ == '__main__':
print 'Parent process %s.'% os.getpid()
for i in range(5):
p = Process(target=run_proc,args=(str(i),))
print 'Process will start.'
#start()启动进程
p.start()
#join()方法实现进程间的同步
p.join()
print 'Process end.'
2.使用Pool类来代表进程池对象
import os,time,random
from multiprocessing import Process,Pool
def run_task(name):
print 'Task %s (pid=%s) is running...'%(name,os.getpid())
time.sleep(random.random()*3)
print 'Task %s end.'% name
if __name__ == '__main__':
print 'Current process %s.' % os.getpid()
p = Pool(processes=3)
for i in range(5):
p.apply_async(run_task,args=(i,))
print 'Waiting for all subprocesses done...'
p.close()
#join()方法会等待所有子进程执行完毕,调用之前必须先调用close()方法
#调用close()之后就不能继续添加新的Process了
p.join()
print 'All subprocesses done.'
3.进程间的通信
假如有创建了多个进程,则进程间的通信是必不可少的,Queue和Pipe的区别在于Pipe常用于两个进程间的通信,Queue经常用于多个进程间的通信
Queue:
from multiprocessing import Process,Queue
import os,time,random
#写数据进程:
#Put方法用以插入数据到队列中,两个可选参数blocked、timeout,如果blocked为True(默认值)
#并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间,如果超时,会抛出Queue.Full异常
#如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常
def proc_write(q,urls):
print 'Process(%s) is writing...' % os.getpid()
for url in urls:
q.put(url)
print 'Put %s to queue...' % url
time.sleep(random.random())
#读数据进程
#Get方法可以从队列读取并且删除一个元素。两个可选参数blocked、timeout
#如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常
#如果blocked为False,分两种情况:如果Queue有一个值可用,则立即返回该值;否则如果队列为空,则立即抛出Queue.Empty异常
def proc_read(q):
print 'Process(%s) is reading...' % os.getpid()
while True:
url = q.get(True)
print 'Get %s from queue,' % url
if __name__ == '__main__':
#父进程创建Queue,并传递给各个子进程:
q = Queue()
proc_writer1 = Process(target=proc_write,args=(q,['url_1','url_2','url_3']))
proc_writer2 = Process(target=proc_write,args=(q,['url_4','url_5','url_6']))
proc_reader = Process(target=proc_read,args=(q,))
#启动子进程proc_write,写入:
proc_writer1.start()
proc_writer2.start()
#启动子进程proc_reader,读取:
proc_reader.start()
#等待proc_writer 结束:
proc_writer1.join()
proc_writer2.join()
#proc_reader 进程是死循环,无法等待其结束,只能强行终止:
proc_reader.terminate()
Pipe:
Pipe方法返回(conn1,conn2)代表一个管道的两个端,Pipe方法有duplex参数,如果duplex参数为TRUE(默认值),那么这个管道是双全工模式,也就是说conn1和conn2均可收发。若duplex为False,conn1只负责接收消息,conn2只负责发送消息,send和recv方法分别是发送和接收消息的方法
from multiprocessing import Process,Pipe
import random,time,os
def proc_send(pipe,urls):
for url in urls:
print 'Process(%s) send: %s' % (os.getpid(),url)
pipe.send(url)
time.sleep(random.random())
def proc_recv(pipe):
while True:
print 'Process(%s) recv: %s' % (os.getpid(),pipe.recv())
time.sleep(random.random())
if __name__ == '__main__':
pipe = Pipe()
p1 = Process(target=proc_send,args=(pipe[0],['url_'+str(i) for i in range(10)]))
p2 = Process(target=proc_recv,args=(pipe[1],))
p1.start()
p2.start()
p1.join()
p2.join()