当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,
如果两个文件同时进行,肯定是不行的,必须是文件写结束后,才可以进行读操作。
或者是多个进程在共享一些资源的时候,同时只能有一个进程进行访问,那就需要锁机制进行控制。
需求:
一个进程写入一个文件,一个进程追加文件,一个进程读文件,同时启动起来
我们可以通过进程的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
原文:http://blog.51cto.com/286577399/2049535