多进程、进程池他们之间的加锁相互应用范例
作者:互联网
在多进程中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
标签:范例,水蜜桃,加锁,完成,--,正产,__,time,进程 来源: https://www.cnblogs.com/YXFate/p/15125177.html