Java教程

多进程、进程池他们之间的加锁相互应用范例

本文主要是介绍多进程、进程池他们之间的加锁相互应用范例,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在多进程中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
这篇关于多进程、进程池他们之间的加锁相互应用范例的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!