【一】进程通信
1.多个进程之间的信息交换过程
2.如何实现
(1)消息队列:把信息从一端放入队列中,另一个进程从另一端将消息取出
非阻塞的,即发送进程不需要等待接收进程的响应即可继续执行。
(2)管道:半双工的通信机制,同时只能一端进行发一端进行收,不能同时收发
(3)队列(管道+锁):生产者-消费者模型。先进先出
【二】队列
(1)创建队列的类(底层就是以管道和锁定的方式实现)
语法:import queue
q = queue.Queue(maxsize)
maxsize是队列中允许最大项数,省略则无大小限制。
from multiprocessing import Queue
q = Queue(5)
(2)方法:
记住:队是先进先出的数据结构
1.队列对象.put(数据)入队<--->相当于push,将数据放入到队列中
如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常
如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
2.队列对象.get()出队<--->相当于pop,将数据读出并删除
如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。
如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常.
3.队列对象.get_nowait()===== 同q.get(False),但是当没有值时会报错
4.队列对象.put_nowait()===== 同q.get(False),但是当队列满时会报错
5.队列对象.empty()===判空
6.队列对象.full()===判满
7.队列对象.qsize()====判队列中数据的数量
"""
full()
empty()
get_nowait()
上述方法能否在并发的场景下精准使用???
不能用!!!
之所以介绍队列是因为它可以支持进程间数据通信
"""
【三】管道
管道:半双工的通信机制,同时只能一端进行发一端进行收,不能同时收发
#Pipe
from multiprocessing import Pipe
# 创建管道对象,获取两个管道对象,可以用一个变量装到时候解包
left_pipe,right_pipe=Pipe()#默认参数dumplex:默认双通道管道
# 方法(都是要先关闭一端一端接或收)传递或接收完记得关闭刚刚在使用的管道
# (1)接收数据
"""
left_pipe.close()
right_pipe.recv()
# (2)发送数据
left_pipe.close()
right_pipe.send()
【四】进程间通信(IPC机制)
1.方式一:子进程与主进程之间通过队列进行通信
直接把队列当作一个子进程进行存放消息
from multiprocessing import Process, Queue
# 创建一个子进程函数
def producer(que_ue):
# 子进程放入消息
que_ue.put('子进程中放入了一条消息')
print('这是主进程中的一个子进程的队列')
if __name__ == '__main__':
# 【一】创建队列对象:注意这里是使用的 multiprocessing 里面的 Queue
que_ue = Queue()
# 【二】创建子进程:目标函数和参数带进去
pro_cess = Process(target=producer, args=(que_ue,))
# 【三】启动子进程
pro_cess.start()
# 【四】主进程获取消息
msg_from_p = que_ue.get()
# 【五】查看消息
print(msg_from_p)
# 这是主进程中的一个子进程的队列
# 子进程中放入了一条消息
2.方式二:子进程与子进程之间借助队列进行通信
生产者消费者的思想,生产者往队列放消息,消费者从队列拿数据
from multiprocessing import Process, Queue
# 创建一个子进程函数
def producer(que_ue):
# 子进程放入消息
que_ue.put('子进程中放入了一条消息')
print('这是主进程中的一个子进程的队列')
def customer(que_ue):
# 在另一个子进程中获取到非本子进程放入的消息
msg_from_producer = que_ue.get()
print('这是来自另一个子进程的消息 :>>>> ', msg_from_producer)
if __name__ == '__main__':
# 【一】创建队列对象:注意这里是使用的 multiprocessing 里面的 Queue
que_ue = Queue()
# 【二】创建子进程:目标函数和参数带进去
p_list = []
pro_producer = Process(target=producer, args=(que_ue,))
pro_customer = Process(target=customer, args=(que_ue,))
# 【三】启动子进程
pro_producer.start()
pro_customer.start()
pro_producer.join()
pro_customer.join()
# 这是主进程中的一个子进程的队列
# 这是来自另一个子进程的消息 :>>>> 子进程中放入了一条消息
【四】生产者消费者模型
# 生产者
负责生产/制作数据
# 消费者
负责消费/处理数据
"""
【五】JoinableQueue模块
● JoinableQueue([maxsize]):这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。
● 通知进程是使用共享的信号和条件变量来实现的。
from multiprocessing import JoinableQueue
q = JoinableQueue()
# 方法介绍:JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
# q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
# q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止