1:Queue
queue用于不同进程间的通讯,但是一旦get出来,队列就会发生改变所以在get的时候应该判空
class Solution():
def __init__(self):
self.name = '乐乐熊'
def fun(q):
time.sleep(2)
q.put('JOKER')
print('装填完毕')
def fnu(q):
time.sleep(1)
q.put([1,2,3,4,'ads'])
print('装填完毕')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=fun,args=(q,))
p2 = Process(target=fnu,args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print('P1,2进入阻塞')
print(q.get())
print(q.get())
q.put(['asdasd'])
print(q.get())
print(q.qsize())
# 加载c1,一个对象
c1 = Solution()
q.put(c1)
print(type(q.get()))
print(q.qsize())
print('结束')
注,运行时如果在IDLE或者Spyder/Vscode等编辑器内运行,无法看到对应的进程显示信息,因此应该在cmd中运行Python ./xxx.py
可以看出Queue遵循着后入先出的规则,若有.get()
前面一定会有.put()
与之对应,在Queue中所有数据被get
出来,其长度为0,此时若再次调用.get()
方法,会报错,因此每次在调用get方法前一定要对当前的Queue
大小进行判断,Queue不仅支持字符串、列表、数字的进程间传递,还支持对象的传递。
2:管道Pipe
Python中的管道支持双向传递和单向传递,其中单向传递结构如下所示:
通常主进程将信息发送到管道当中,子进程从管道中接收主进程发送的信息,一旦子进程接收到了该信息后,管道中的信息数减1,其他的子进程就无法获取该信息。而双向管道则是子进程也可以向主进程发送信息,主进程接收各个子进程发送的信息。下列代码向我们解释了双向管道的工作流程:
def func(conn):
conn.send("message")
def fnuc(conn):
conn.send('Newtest')
def jieshou(conn):
print(conn.recv())
if __name__ == "__main__":
(conn1,conn2) = Pipe()
p1 = Process(target=func,args=(conn1,))
p1.start()
print(conn2.recv())
p2 = Process(target=func,args=(conn2,))
p2.start()
print(conn1.recv())
p3 = Process(target=fnuc,args=(conn2,))
p3.start()
print(conn1.recv())
conn2.send('进程4测试')
p4 = Process(target=jieshou,args=(conn1,))
p4.start()
p4.join()
# 先进先出
conn2.send('连续第1天')
conn1.send('连续第2天')
conn2.send('连续第3天')
conn1.send('连续第4天')
conn2.send('不连续了md')
print(conn1.recv())
print(conn1.recv())
print(conn2.recv())
print(conn2.recv())
# print(conn1.recv())
print('一切都结束了')
1:可以看出管道只能适用于两个进程一读一写的情况,管道只能一个端口发送一个端口接收,或者一个端口接收一个端口发送
2: 有多少个发送,就应当有多少个接收,可以连续用两个管道切换发送,接收的时候,左右两个管道切换接收即可
3:管道中的信息接收符合先入先出的规则
值得注意的是,管道没有东西的时候不能接收,会阻塞主进程
3:Manager
Manager可以建立一个全局共享变量,常用的共享变量有dict形式和list形式且共享变量支持上锁(Lock.acquire(),Lock.release()
),下面针对dict形式进行详细说明
import time
from multiprocessing import Process,Queue,Pool,Manager,Pipe
class Solution():
def __init__(self):
self.name = '乐乐熊'
self.age = 24
def add_data(p_dict,key,value):
p_dict[key] = value
def show(p_dict):
print(p_dict['3'].age)
def del_key(p_dict):
p_dict["a"]=['zzh','zww','xzm','mym']
if __name__ == "__main__":
progress = Manager().dict()
c1 = Solution()
progress['3']=c1
p1 = Process(target=add_data,args=(progress,"a",1))
p2 = Process(target=add_data,args=(progress,"b",2))
p3 = Process(target=show,args=(progress,))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print(progress['3'].name)
print(progress)
p4 = Process(target=del_key,args=(progress,))
p4.start()
p4.join()
print(progress)
运行后结构显示如下:
分析结果,可以看出共享dict{}
变化是实时的,子进程和主进程都可以对其进行修改。