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() 方法會阻塞已調用進程鎖的進程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章