python multiprocess Lock and shared memory

Multiprocess Lock

  • lock = multiprocessing.Lock() creates a lock
  • lock.acquire() acquisition lock
  • lock.release() release lock
  • with lock: Automatic acquisition and release locks are similar to with open() as f:

Characteristic:

Who grabs the lock first and who executes it first. After the execution of the process is completed, other processes grab the lock and execute it again.

When the program is unlocked:

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...')

# Implementation results:
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

There is no order in luck, and the three processes run alternately.

When the program is locked

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...')

# Implementation results:
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

Only when one of the processes has been executed will the other processes execute, and who gets the lock first and who executes first.

Shared memory

Agr = multiproessing. Value (type, value) creates a variable agre ement for shared memory

    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 declares the type of shared variable agre ement
  • Value shares the value of variable agre ement
  • Agr. value gets the value of the shared variable agre

Array = muliproessing. Array (type, values) creates an array arr of shared memory

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)

Example:

'''
//Nobody answered the question? Xiaobian created a Python learning and communication QQ group: 857662006 to find like-minded partners.
//Mutual help, there are good video learning tutorials and PDF e-books in the group!
'''
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...')
    
//Implementation results:
[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-------

Process p3 is executed and locked first, process P is executed during p3 execution, because P does not call lock and uses join() method to block other processes, only when p is executed.

p3 will continue to execute, p1 will grab the lock and execute after p3 is executed

Both p1 and p3 accumulate the shared memory num, so the value of num keeps increasing.
P re-assigns each value in the arr shared array, so when the P process completes, the values in the arr shared array change.

As can be seen from the above example:

1. Process locks only lock processes that call them, and processes that do not call them are unaffected.
2. Using join() method in processes that do not call process locks blocks processes that have called process locks

Keywords: Python

Added by xylex on Thu, 10 Oct 2019 10:31:30 +0300