python 多进程锁Lock和共享内存
多进程锁
-
lock = multiprocessing.Lock() 创建一个锁
-
lock.acquire() 获取锁
-
lock.release() 释放锁
-
with lock: 自动获取、释放锁 类似于 with open() as f:
-
特点:
谁先抢到锁谁先执行,等到该进程执行完成后,其它进程再抢锁执行
-
当程序不加锁时:
import multiprocessing import time def add(num, value, lock): print('add{0}:num={1}'.format(value, num)) for i in xrange(0, 2): num += value print('add{0}:num={1}'.format(value, num)) time.sleep(1) if __name__ == '__main__': lock = multiprocessing.Lock() num = 0 p1 = multiprocessing.Process(target=add, args=(num, 1, lock)) p2 = multiprocessing.Process(target=add, args=(num, 3, lock)) p3 = multiprocessing.Process(target=add, args=(num, 5, lock)) p1.start() p2.start() p3.start() print('main end...') # 执行结果: add1:num=0 add1:num=1 main end... add3:num=0 add3:num=3 add5:num=0 add5:num=5 add3:num=6 add1:num=2 add5:num=10 运得没有顺序,三个进程交替运行
-
当程序加锁时
import multiprocessing import time def add(num, value, lock): try: lock.acquire() print('add{0}:num={1}'.format(value, num)) for i in xrange(0, 2): num += value print('add{0}:num={1}'.format(value, num)) time.sleep(1) except Exception as err: raise err finally: lock.release() if __name__ == '__main__': lock = multiprocessing.Lock() num = 0 p1 = multiprocessing.Process(target=add, args=(num, 1, lock)) p2 = multiprocessing.Process(target=add, args=(num, 3, lock)) p3 = multiprocessing.Process(target=add, args=(num, 5, lock)) p1.start() p2.start() p3.start() print('main end...') # 执行结果: add3:num=0 add3:num=3 main end... add3:num=6 add1:num=0 add1:num=1 add1:num=2 add5:num=0 add5:num=5 add5:num=10 只有当其中一个进程执行完成后,其它的进程才会去执行,且谁先抢到锁谁先执行
共享内存
-
agre = multiproessing.Value(type, value) 创建一个共享内存的变量agre
def Value(typecode_or_type, *args, **kwds): ''' Returns a synchronized shared object ''' from multiprocessing.sharedctypes import Value return Value(typecode_or_type, *args, **kwds)
type 声明共享变量agre的类型
value 共享变量agre的值
-
agre.value 获取共享变量agre的值
-
arr = muliproessing.Array(type, values) 创建一个共享内存的数组arr
def Array(typecode_or_type, size_or_initializer, **kwds): ''' Returns a synchronized shared array ''' from multiprocessing.sharedctypes import Array return Array(typecode_or_type, size_or_initializer, **kwds)
-
例子:
import multiprocessing
import time
def add(num, value, lock):
try:
lock.acquire()
print('add{0}:num={1}'.format(value, num.value))
for i in xrange(0, 2):
num.value += value
print('add{0}:num={1}'.format(value, num.value))
print('-------add{} add end-------'.format(value))
time.sleep(1)
except Exception as err:
raise err
finally:
lock.release()
def change(arr):
for i in range(len(arr)):
arr[i] = 1
if __name__ == '__main__':
lock = multiprocessing.Lock()
num = multiprocessing.Value('i', 0)
arr = multiprocessing.Array('i', range(10))
print(arr[:])
p1 = multiprocessing.Process(target=add, args=(num, 1, lock))
p3 = multiprocessing.Process(target=add, args=(num, 3, lock))
p = multiprocessing.Process(target=change, args=(arr,))
p1.start()
p3.start()
p.start()
p.join()
print(arr[:])
print('main end...')
执行结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
add3:num=0
add3:num=3
-------add3 add end-------
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
main end...
add3:num=6
-------add3 add end-------
add1:num=6
add1:num=7
-------add1 add end-------
add1:num=8
-------add1 add end-------
先执行进程p3并加锁,p3执行过程中进程p执行,因为p没有调用锁且使用了join()方法,阻塞了其它进程,只有当p执行完成后
p3才会继续执行,p3执行完成后,p1抢到锁并执行
p1、p3 都对共享内存num 进行累加操作,所以num的值一直在增加
p 对 arr 共享数组中的每个值进行了重新赋值的操作,所以当P进程执行完成后,arr数组中的值均发生了变化
由上例可以看出:
1、进程锁只对调用它的进程起锁的作用,未调用该锁的进程不受影响
2、在未调用进程锁的进程中使用 join() 方法会阻塞已调用进程锁的进程