一 前言
我们知道Python中多进程是相互执行互不干扰的,但是如果多进程之间需要对同一资源对象进行操作或者多个进程之间有相互依赖的,那就需要一个共享变量供多进程使用。Python multiprocessing 多进程之间相互协调的方式有如下几种: Lock:锁,Queue:队列, Semaphore:信号量 ,Event:事件,Pipe:管道 。
后续文章会逐个介绍这几种方式,本文学习 Lock:锁 。
Python资源共享群:484031800
二 实践
当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突。思考一个场景无事务状态下共同访问某个内存变量或者多个进程要访问读写同一个文件。
初始化lock很简单:
lock = Lock() 即可创建一个锁对象,
该对象为全局对象,能被所有的子进程使用。
2.1 no lock
# encoding: utf-8 """ author: [email protected] time: 2019/8/10 5:48 PM func: """ from multiprocessing import Process, Value, Lock def sub(num): num.value += 1 if __name__ == '__main__': lock = Lock() # 创建锁对象 val = Value('i', 0) # Value是通过共享内存的方式共享数据 初始值 val 为0 proc = [Process(target=sub, args=(val,)) for i in xrange(100)] for p in proc: p.start() for p in proc: p.join() print '经过100次累加之后 val 的值是: %d' %val.value
结果
因为共享内存中的val能被同时访问,存在val=90 的时候 ,被多个并发加1结果val=91 ,比如3次,结果就是val=98
2.2 lock
# encoding: utf-8 """ author: [email protected] time: 2019/8/10 5:38 PM func: """ from multiprocessing import Process, Value, Lock def sub(num,lock): # 传入的lock对象 lock.acquire() # 申请锁,lock对象变为locked,并且阻塞其他进程获取lock对象 num.value += 1 lock.release() # 释放锁,lock对象变为unlocked,其他进程可以重新获取lock对象 if __name__ == '__main__': lock = Lock() # 创建锁对象 val = Value('i', 0) proc = [Process(target=sub, args=(val,lock)) for i in xrange(100)] for p in proc: p.start() for p in proc: p.join() print '经过100次累加之后 val 的值是: %d' % val.value
利用lock 就能将+1 的动作串行化。确保不会发生写覆盖的现象。
结果