多程序、程序池他們之間的加鎖相互應用範例
阿新 • • 發佈:2021-08-10
在多程序中Lock鎖,都有自帶上下文管理器的方法,所以具備上下文管理器的功能
1.普通多程序【單鎖】
from multiprocessing import Lock, Process import time def producer(i, lock): lock.acquire() print(f'正在正產{i}份水蜜桃') time.sleep(0.8) print(f'生產完成{i}份水蜜桃') lock.release() if __name__ == '__main__': t1 = time.time() lock = Lock() lst_p = [] for i in range(4): p = Process(target=producer, args=(i + 1, lock)) p.start() lst_p.append(p) [p.join() for p in lst_p] t2 = time.time() print(f'主執行緒結束總耗時{t2 - t1:0.2f}S') # 輸出結果: # 正在正產1份水蜜桃 # 生產完成1份水蜜桃 # 正在正產2份水蜜桃 # 生產完成2份水蜜桃 # 正在正產3份水蜜桃 # 生產完成3份水蜜桃 # 正在正產4份水蜜桃 # 生產完成4份水蜜桃 # 主執行緒結束總耗時3.53S
2.關於多程序的上下文管理器【單鎖】
- 多程序鎖[自帶上下文管理器的魔法方法]:__enter__與__exit__
from multiprocessing import Lock, Process import time def producer(i, lock): with lock: print(f'正在正產{i}份水蜜桃') time.sleep(0.8) print(f'生產完成{i}份水蜜桃') if __name__ == '__main__': t1 = time.time() lock = Lock() lst_p = [] for i in range(4): p = Process(target=producer, args=(i + 1, lock)) p.start() lst_p.append(p) [p.join() for p in lst_p] t2 = time.time() print(f'主執行緒結束總耗時{t2 - t1:0.2f}S') # 輸出結果: # 正在正產1份水蜜桃 # 生產完成1份水蜜桃 # 正在正產2份水蜜桃 # 生產完成2份水蜜桃 # 正在正產3份水蜜桃 # 生產完成3份水蜜桃 # 正在正產4份水蜜桃 # 生產完成4份水蜜桃 # 主執行緒結束總耗時3.52S
3.多程序訊號量【多鎖】上下文管理器
from multiprocessing import Semaphore, Process import time def producer(i, sema): with sema: print(f'正在正產{i}份水蜜桃') time.sleep(0.8) print(f'生產完成{i}份水蜜桃') if __name__ == '__main__': t1 = time.time() sema = Semaphore(3) lst_p = [] for i in range(16): p = Process(target=producer, args=(i + 1, sema)) p.start() lst_p.append(p) [p.join() for p in lst_p] t2 = time.time() print(f'主執行緒結束總耗時{t2 - t1:0.2f}S') # 輸出結果: # 正在正產1份水蜜桃 # 正在正產2份水蜜桃 # 正在正產3份水蜜桃 # 生產完成1份水蜜桃 # 正在正產4份水蜜桃 # 生產完成2份水蜜桃 # 正在正產5份水蜜桃 # 生產完成3份水蜜桃 # 正在正產7份水蜜桃 # 生產完成4份水蜜桃 # 正在正產8份水蜜桃 # 生產完成5份水蜜桃 # 正在正產9份水蜜桃 # 生產完成7份水蜜桃 # 正在正產6份水蜜桃 # 生產完成8份水蜜桃 # 正在正產10份水蜜桃 # 生產完成9份水蜜桃 # 正在正產11份水蜜桃 # 生產完成6份水蜜桃 # 正在正產12份水蜜桃 # 生產完成10份水蜜桃 # 正在正產13份水蜜桃 # 生產完成11份水蜜桃 # 正在正產14份水蜜桃 # 生產完成12份水蜜桃 # 正在正產15份水蜜桃 # 生產完成13份水蜜桃 # 正在正產16份水蜜桃 # 生產完成14份水蜜桃 # 生產完成15份水蜜桃 # 生產完成16份水蜜桃 # 主執行緒結束總耗時5.21S
4.程序池通過Manager實現多程序間資料共享,從而實現非同步加多鎖機制
# 程序池之間是無法通過直接傳入鎖加鎖,所以引入了Manager可以實現加鎖機制
# Manager實現多個程序之間的共享記憶體,並修改資料
# 這裡不需要加鎖,因為manager已經預設給你加鎖了
Manager支援的型別有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array
from multiprocessing import Pool, Manager
import time
def producer(i, lock):
print(f'--{i}準備工作--')
with lock:
print(f'正在正產{i}份水蜜桃')
time.sleep(10)
print(f'生產完成{i}份水蜜桃')
return i
if __name__ == '__main__':
t1 = time.time()
m = Manager()
sema = m.Semaphore(3)
p = Pool(5)
lst_res = []
for i in range(16):
res = p.apply_async(producer, args=(i + 1, sema))
lst_res.append(res)
p.close()
p.join()
[print(res.get()) for res in lst_res]
t2 = time.time()
print(f'主執行緒結束總耗時{t2 - t1:0.2f}S')
# 輸出結果:
# --1準備工作--
# 正在正產1份水蜜桃
# --2準備工作--
# 正在正產2份水蜜桃
# --3準備工作--
# 正在正產3份水蜜桃
# --4準備工作--
# --5準備工作--
# 生產完成1份水蜜桃
# 正在正產4份水蜜桃
# --6準備工作--
# 生產完成2份水蜜桃
# 正在正產5份水蜜桃
# --7準備工作--
# 生產完成3份水蜜桃
# 正在正產6份水蜜桃
# --8準備工作--
# 生產完成4份水蜜桃
# 正在正產7份水蜜桃
# --9準備工作--
# 生產完成5份水蜜桃
# 正在正產8份水蜜桃
# --10準備工作--
# 生產完成6份水蜜桃
# 正在正產9份水蜜桃
# --11準備工作--
# 生產完成7份水蜜桃
# 正在正產10份水蜜桃
# --12準備工作--
# 生產完成8份水蜜桃
# 正在正產11份水蜜桃
# --13準備工作--
# 生產完成9份水蜜桃
# 正在正產12份水蜜桃
# --14準備工作--
# 生產完成10份水蜜桃
# 正在正產13份水蜜桃
# --15準備工作--
# 生產完成11份水蜜桃
# 正在正產14份水蜜桃
# --16準備工作--
# 生產完成12份水蜜桃
# 正在正產15份水蜜桃
# 生產完成13份水蜜桃
# 正在正產16份水蜜桃
# 生產完成14份水蜜桃
# 生產完成15份水蜜桃
# 生產完成16份水蜜桃
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
# 11
# 12
# 13
# 14
# 15
# 16
# 主執行緒結束總耗時60.70S