这是看书笔记
python提供了多种进程通信的方式,比如说Queue,Pipe,Value+Array等。
其中Queue主要用来在多个进程之间实现通信。Pipe常用来在两个进程之间实现通信。
Queue是多进程安全队列,Queue通过put和get方法来实现多进程之间的数据传递。
put方法用于将数据插入到队列,有两个可选参数,一个是blocked,一个时timeout,
如果blocked为True,那么这个方法就会阻塞timeout指定的时间,直到队列有剩余的
空间。如果超时,则抛出Queue.Full异常。
get方法用于将数据从队列中取出,也有两个可选参数,blocked和timeout,如果blocked
为True,那么这个方法会阻塞timeout指定的时间,直到队列中有数据。如果超时,则抛出
Queue.Empty异常。
import os,time,random from multiprocessing import Process,Queue def write_proc(q,urls): print("Process %s Running..."%(os.getpid())) for url in urls: q.put(url) print("put %s in queue..."%url) time.sleep(random.random()*3) def read_proc(q): print("Process %s Running..."%(os.getpid())) while True: url=q.get(True) print("get %s from queue..."%url) if __name__=='__main__': print("Main Process %s Running..."%(os.getpid())) q=Queue() writer_proc1=Process(target=write_proc,args=(q,['url1','url2','url3','url4'])) writer_proc2=Process(target=write_proc,args=(q,['url5','url6','url7','url8'])) reader_proc=Process(target=read_proc,args=(q,)) writer_proc1.start() writer_proc2.start() reader_proc.start() writer_proc1.join() writer_proc2.join() #在这里由于reader_proc执行函数时一个死循环,所以只能通过手动终结进程 reader_proc.terminate() print("Main Process end")
这个Queue应该内部实现了一些互斥操作,使得多个进程能对其访问。
Pipe常用来在两个进程之间进行通信。该方法返回一个二元元组 (conn1,conn2),代表一个管道的两端。Pipe方法有个duplex参数。默认为True,当其为True时,表示该管道处于全双工模式下。conn1和conn2都可以进行收发。当期为False时,表示该管道处于半双工模式下,conn只能进行接收消息,conn2只能发送消息。
send和recv方法分别是发送和接收消息的方法。
import os,time,random from multiprocessing import Process,Pipe def proc_send(p,urls): for url in urls: print("Process %s send %s..."%(os.getpid(),url)) p.send(url) time.sleep(random.random()*4) def proc_recv(p): while True: url=p.recv() print("Process %s recv %s..."%(os.getpid(),url)) if __name__=='__main__': print("Main Process %s Running..."%(os.getpid())) pipe=Pipe() p1=Process(target=proc_send,args=(pipe[0],['url1','url2','url3','url4'])) p2=Process(target=proc_recv,args=(pipe[1],)) p1.start() p2.start() p1.join() p2.terminate() print("Main Process End....")
为了让p2能够一直接收从管道传过来的数据,在接收数据时,将过程放在一个循环中,监听pipe,所以
最后p2的终结只能通过terminate来强制终结,如果使用join方法,那么主进程会一直阻塞。