進程之間的通信
import time,threading
# 首先線程之間是共享內(nèi)存地址的
def info(que):
que.put(1)
if __name__ == "__main__":
q = queue.Queue() #創(chuàng)建一個線程隊列queue
t = threading.Thread(target=info,args=(q,))
t.start()
print(q.get())
所以取值成成功
image.png
# 現(xiàn)在,我們把線程隊列改進程隊列
from multiprocessing import Process,Queue
import threading
def info(que):
que.put(1)
if __name__ == "__main__":
q = Queue() # 創(chuàng)建一個進程隊列
t = threading.Thread(target=info,args=(q,)) #創(chuàng)建一個線程實例
t.start()
print(q.get())
咦。這樣好像我們也訪問成功了。但是不對啊。我們明明創(chuàng)建的是進程隊列啊
是的,但實際上是我們創(chuàng)建的線程實例,線程共享內(nèi)存地址,所以我們也訪問成功
image.png
接下來,我們把線程實例換成進程實例,隊列換成線程隊列
from multiprocessing import Process,Queue
import queue
def info(que):
que.put(1)
if __name__ == "__main__":
q = queue.Queue() # 創(chuàng)建一個線程隊列
t = Process(target=info,args=(q,)) #創(chuàng)建一個線程實例
t.start()
print(q.get())
image.png
咦,怎么報錯了呢。因為進程是獨立空間的,在父進程創(chuàng)建一個線程隊列把它傳給子進程。進程之間無法相互訪問
那怎么解決這個問題呢
from multiprocessing import Process,Queue
import queue
def info(que):
que.put(1)
if __name__ == "__main__":
q = Queue() # 創(chuàng)建一個進程隊列
t = Process(target=info,args=(q,)) #創(chuàng)建一個進程實例
t.start()
print(q.get())
咦。好像訪問成功了。為什么呢?
因為進程隊列Queue作為參數(shù)傳子進程,實際上是克隆了一份隊列內(nèi)存地址傳給了子進程,通過內(nèi)存地址操作,將數(shù)據(jù)儲存在一個中間地址,并進行pickle序列化。
而父進程想要訪問子進程傳入的數(shù)據(jù),就必須去訪問中間地址,并進行pickle反序列化。這樣就完成了進程之間的通信
image.png
manager(進程數(shù)據(jù)共享)
from multiprocessing import Process,Manager
import os
def r(d,l):
d[os.getpid()] = os.getpid()
l.append(os.getpid())
print(l)
if __name__ == "__main__":
manager = Manager()
dic = manager.dict() # 定義一個可以進程之間共享數(shù)據(jù)的字典
lis = manager.list()
process_list = []
for i in range(5):
p = Process(target=r,args=(dic,lis))
process_list.append(p)
p.start()
for i in process_list:
i.join()
print(dic)
print(lis)