python进程间通信常用Queue和Pipe,Pipe常用来在两个进程间通信,Queue常用来在多个进程间通信。

Queue实现多进程通信

Queue是多进程安全的通信方式,常用方法Put和Get。

Put方法:

用于插入数据到队列中,有两个参数:blocked和timeout。

blocked为默认值True时,timeout为正值时,该方法会发生阻塞timeout指定时间长度的时间,直到队列有剩余的时间,如果超过timeout 指定的时间长度,则抛出Queue.Full异常。如果blocked为Flase时,但是队列已满,会立即抛出Queue.Full异常。

Get方法

从队列读取并且删除一个元素。该方法有两个参数blocked和timeout。

blocked为默认值True时,并且timeout为正值时,在timeout指定时间长度内没有取到任何元素,会抛出Queue.Empty。如果blocked为False时,如果Queue中有值可用,则立即返回该值,如果队列为空,则立即抛出Queue.Empty异常。

例子:在父进程汇总创建三个子进程,两个子进程往Queue中写入数据,一个子进程从Queue中读取数据。

from multiprocessing import Process,Queueimport os,time,random

# 写入数据的方法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())
# 读取数据的方法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,['url1','url2','url3']))
    proc_writer2 = Process(
target=proc_write,args=(q,['url_4','url_5','url_6']))
    proc_reader = Process(
target=proc_read,args=(q,))
# 启动子进程writer,写入
   
proc_writer1.start()
    proc_writer2.start()
# 启动子进程reader,读取
   
proc_reader.start()# 等待写进程结束
   
proc_writer1.join()
    proc_writer2.join()
# 强制结束读进程
   
proc_reader.terminate()

爬虫预备知识-进程间通信_进程间通信

Pipe通信机制

Pipe常用语两个进程间的通信,两个进程分别位于管道的两端。

Pipe方法返回(conn1,conn2)代表一个管道的两个端,当Pipe方法的duplex参数为默认值True时,那么这个管道是全双工模式,即conn1和conn2都可以接收和发送消息。当duplex为False时,conn1只负责接收消息,conn2只负责发送消息,其中send和recv分别是发送和接收消息的方法。

在全双工模式下,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息接收,recv方法会一直堵塞。如果管道已经被关闭,则recv方法会抛出EOFError。

例子:创建两个进程,一个子进程通过Pipe发送数据,一个子进程通过Pipe接收数据。

import multiprocessingimport randomimport 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) rev:%s'%(os.getpid(),pipe.recv()))
        time.sleep(random.random())

if __name__ == '__main__':
    pipe = multiprocessing.Pipe()
    p1 = multiprocessing.Process(
target=proc_send,args=(pipe[0],['url_'+str(i) for i in range(10)]))
    p2 = multiprocessing.Process(
target=proc_recv,args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

 

爬虫预备知识-进程间通信_进程间通信_02