並發通信Manage,隊列, 互斥鎖
阿新 • • 發佈:2018-08-18
自加 target 才會 解決方案 range 子進程 color 並且 資源競爭
Manage
進程間的通信是被限制的
from multiprocessing import Process a = 1 def func(): global a # 聲明全局變量 a = 2 # 修改全局變量 func() print(a) p = Process(target=func) p.start() p.join() print(a)
兩個結果,第一個是2,第二個是1-----> 進程內存空間是獨立的
解決方案:開辟一個新的進程空間,通過代理器和管理器進行通信
1, 管理器負責與公共進程通信
2, 代理負責操作共享空間
from multiprocessing import Process, Manage(管理器) mgr = Manage() # 先開啟一個子進程(守護進程),並且返回一個用來通信的管理器 shared_list = mgr.list() # 通過Manage管理器開啟一個公共l列表空間(代理) def func(lis): lis.appent(‘hello‘) p = Process(target=func, args=(shared_list, )) p.start(0 p.join() print(shared_list) --> [‘hello‘]
這裏需要知道,可以開啟的代理空間有以下幾個:
mgr.list() 列表
mgr.dict() 字典
mgr.Queue() 隊列
隊列 先入先出
隊列操作:
入列:put()
出列:get()
測試空:empty() 近似值
測試滿:funll() 近似值
隊列長度:qsize() 近似值
任務結束: task_done()
等待完成:join()
需要了解的是,隊列中存在一個計數器的概念,當put的時候,計數器會加1,當task_done時,計數器減1
可以用join進行測試,當計數器不是0,隊列會阻塞,只有當計數器為0時,才會解阻塞
線程間的通信不存在限制,但是會存在資源競爭的問題,即同時執行的線程,公用共享資源的時候,會搶占資源,導致數據亂序
所以需要互斥鎖來鎖定某些操作
import threading from Thread, Lock lock = Lock() # 實例化一個鎖 with lock: xxxxxxxx ‘‘‘ 或者: lock.acquire() # 上鎖 xxxxxxxx lock.release() # 解鎖 xxxxxx能少則少 鎖不能加太多,會大大下降性能 ‘‘‘
1 from threading import Thread, Lock 2 3 lock = Lock() # 實例化一個鎖的實例 4 a = 0 5 6 def incr(n): # 自加 7 global a 8 for i in range(n): 9 with lock: 10 a += 1 11 12 def decr(n): # 自減 13 global a 14 for i in range(n): 15 with lock: 16 a -= 1 17 18 t = Thread(target=incr, args=(1000000, )) 19 t2 = Thread(target=decr, args=(1000000, )) 20 t.start() 21 t2.start() 22 t.join() 23 t2.join() 24 print(a) 25 26 --> 0
如果不加鎖,線程之間會競爭資源,得到的結果是一個隨機值
並發通信Manage,隊列, 互斥鎖