37. Python 多进程锁 多进程共享内存
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了37. Python 多进程锁 多进程共享内存相关的知识,希望对你有一定的参考价值。
Lock组件
当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,
如果两个文件同时进行,肯定是不行的,必须是文件写结束后,才可以进行读操作。
或者是多个进程在共享一些资源的时候,同时只能有一个进程进行访问,那就需要锁机制进行控制。
需求:
一个进程写入一个文件,一个进程追加文件,一个进程读文件,同时启动起来
我们可以通过进程的join()方法来实现,这是一种方法,本节用Lock(进程锁)来实现。
函数说明:
# lock = multiprocessing.Lock()
# lock.acquire() ? ? ? ? ? ? ? ?#获得锁
# lock.release() ? ? ? ? ? ? ? ?#释放锁
先写不加锁的程序:
#不加锁
# number ?+1
# number ?+3
import?multiprocessing import?time def?add(number,value,lock): ????print?("init?add{0}?number?=?{1}".format(value,?number)) ????for?i?in?xrange(1,?6): ????????number?+=?value ????????time.sleep(1) ????????print?("add{0}?number?=?{1}".format(value,?number)) ???????? if?__name__?==?"__main__": ????lock?=?multiprocessing.Lock() ????number?=?0 ????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock)) ????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock)) ????p1.start() ????p2.start() ????print?("main?end")
结果:
main?end init?add1?number?=?0 init?add3?number?=?0 add1?number?=?1 add3?number?=?3 add1?number?=?2 add3?number?=?6 add1?number?=?3 add3?number?=?9 add1?number?=?4 add3?number?=?12 add1?number?=?5 add3?number?=?15
再写加锁的程序:
import?multiprocessing import?time def?add(number,value,lock): ????with?lock: ????print?("init?add{0}?number?=?{1}".format(value,?number)) ????for?i?in?xrange(1,?6): ????????number?+=?value ????????time.sleep(1) ????????print?("add{0}?number?=?{1}".format(value,?number)) ???????? if?__name__?==?"__main__": ????lock?=?multiprocessing.Lock() ????number?=?0 ????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock)) ????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock)) ????p1.start() ????p2.start() ????print?("main?end")
结果:
main?end init?add1?number?=?0 #add1优先抢到锁,优先执行 add1?number?=?1 add1?number?=?2 add1?number?=?3 add1?number?=?4 add1?number?=?5 init?add3?number?=?0 #add3被阻塞,等待add1执行完成,释放锁后执行add3 add3?number?=?3 add3?number?=?6 add3?number?=?9 add3?number?=?12 add3?number?=?15
使用 lock.acquire() 和 lock.release()
import?multiprocessing import?time def?add(number,value,lock): ????lock.acquire() ????try: ????????print?("init?add{0}?number?=?{1}".format(value,?number)) ????????for?i?in?xrange(1,?6): ????????????number?+=?value ????????????time.sleep(1) ????????????print?("add{0}?number?=?{1}".format(value,?number)) ????except?Exception?as?e: ????????raise?e ????finally: ????????lock.release() if?__name__?==?"__main__": ????lock?=?multiprocessing.Lock() ????number?=?0 ????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock)) ????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock)) ????p1.start() ????p2.start() ????print?("main?end")
结果:
main?end init?add1?number?=?0 add1?number?=?1 add1?number?=?2 add1?number?=?3 add1?number?=?4 add1?number?=?5 init?add3?number?=?0 add3?number?=?3 add3?number?=?6 add3?number?=?9 add3?number?=?12 add3?number?=?15
共享内存
python的multiprocessing模块也给我们提供了共享内存的操作
一般的变量在进程之间是没法进行通讯的,multiprocessing 给我们提供了 Value 和 Array 模块,他们可以在不通的进程中共同使用
例子:不加锁,让number加完1后再继续加3,再继续加一,再继续加3...
import?multiprocessing import?time def?add(number,add_value): ????try: ????????print?("init?add{0}?number?=?{1}".format(add_value,?number.value)) ????????for?i?in?xrange(1,?6): ????????????number.value?+=?add_value ????????????print?("***************add{0}?has?added***********".format(add_value)) ????????????time.sleep(1) ????????????print?("add{0}?number?=?{1}".format(add_value,?number.value)) ????except?Exception?as?e: ????????raise?e ???????? if?__name__?==?"__main__": ????number?=?multiprocessing.Value(‘i‘,?0) ????p1?=?multiprocessing.Process(target=add,args=(number,?1)) ????p2?=?multiprocessing.Process(target=add,args=(number,?3)) ????p1.start() ????p2.start() ????print?("main?end")
打印结果:
main?end init?add1?number?=?0 ***************add1?has?added*********** init?add3?number?=?1 ***************add3?has?added*********** add1?number?=?4 ***************add1?has?added*********** add3?number?=?5 ***************add3?has?added*********** add1?number?=?8 ***************add1?has?added*********** add3?number?=?9 ***************add3?has?added*********** add1?number?=?12 ***************add1?has?added*********** add3?number?=?13 ***************add3?has?added*********** add1?number?=?16 ***************add1?has?added*********** add3?number?=?17 ***************add3?has?added*********** add1?number?=?20 add3?number?=?20
再给加上锁:
加1的进程加完后,再执行加上3的进程
import?multiprocessing import?time def?add(number,add_value,lock): ????lock.acquire() ????try: ????????print?("init?add{0}?number?=?{1}".format(add_value,?number.value)) ????????for?i?in?xrange(1,?6): ????????????number.value?+=?add_value ????????????print?("***************add{0}?has?added***********".format(add_value)) ????????????time.sleep(1) ????????????print?("add{0}?number?=?{1}".format(add_value,?number.value)) ????except?Exception?as?e: ????????raise?e ????finally: ????????lock.release() ???????? if?__name__?==?"__main__": ????lock?=?multiprocessing.Lock() ????number?=?multiprocessing.Value(‘i‘,?0) ????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock)) ????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock)) ????p1.start() ????p2.start() ????print?("main?end")
执行结果(对比上面):
main?end init?add1?number?=?0 ***************add1?has?added*********** add1?number?=?1 ***************add1?has?added*********** add1?number?=?2 ***************add1?has?added*********** add1?number?=?3 ***************add1?has?added*********** add1?number?=?4 ***************add1?has?added*********** add1?number?=?5 init?add3?number?=?5 ***************add3?has?added*********** add3?number?=?8 ***************add3?has?added*********** add3?number?=?11 ***************add3?has?added*********** add3?number?=?14 ***************add3?has?added*********** add3?number?=?17 ***************add3?has?added*********** add3?number?=?20
多进程共享内存实现:
import?multiprocessing import?time def?add(number,add_value,lock): ????lock.acquire() ????try: ????????print?("init?add{0}?number?=?{1}".format(add_value,?number.value)) ????????for?i?in?xrange(1,?6): ????????????number.value?+=?add_value ????????????print?("***************add{0}?has?added***********".format(add_value)) ????????????time.sleep(1) ????????????print?("add{0}?number?=?{1}".format(add_value,?number.value)) ????????except?Exception?as?e: ????????????raise?e ????????finally: ????????????lock.release() def?change(arr): ????for?i?in?range(len(arr)): ????????arr[i]?=?-arr[i] ???????? if?__name__?==?"__main__": ????lock?=?multiprocessing.Lock() ????number?=?multiprocessing.Value(‘i‘,?0) ????arr?=?multiprocessing.Array(‘i‘,?range(10)) ????print?(arr[:]) ????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock)) ????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock)) ????p3?=?multiprocessing.Process(target=change,args=(arr,)) ????p1.start() ????p2.start() ????p3.start() ????p3.join() ????print?(arr[:]) ????print?("main?end")
结果:
[0,?1,?2,?3,?4,?5,?6,?7,?8,?9] init?add3?number?=?0 ***************add3?has?added*********** [0,?-1,?-2,?-3,?-4,?-5,?-6,?-7,?-8,?-9] main?end add3?number?=?3 ***************add3?has?added*********** add3?number?=?6 ***************add3?has?added*********** add3?number?=?9 ***************add3?has?added*********** add3?number?=?12 ***************add3?has?added*********** add3?number?=?15 init?add1?number?=?15 ***************add1?has?added*********** add1?number?=?16 ***************add1?has?added*********** add1?number?=?17 ***************add1?has?added*********** add1?number?=?18 ***************add1?has?added*********** add1?number?=?19 ***************add1?has?added*********** add1?number?=?20
以上是关于37. Python 多进程锁 多进程共享内存的主要内容,如果未能解决你的问题,请参考以下文章
python 归纳 (二十)_多进程数据共享和同步_共享内存Value & Array