天天看點

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)           

例子:

'''
遇到問題沒人解答?小編建立了一個Python學習交流QQ群:857662006 尋找有志同道合的小夥伴,
互幫互助,群裡還有不錯的視訊學習教程和PDF電子書!
'''
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() 方法會阻塞已調用程序鎖的程序