• 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() 方法会阻塞已调用进程锁的进程
    
  • 相关阅读:
    02-09 对数线性回归(波士顿房价预测)
    02-02 感知机原始形式(鸢尾花分类)
    02-19 k近邻算法(鸢尾花分类)
    02-21 决策树ID3算法
    A-02 梯度下降法
    09-01 Tensorflow1基本使用
    02-34 非线性支持向量机(鸢尾花分类)+自定义数据分类
    [Python]网络爬虫(四):Opener与Handler的介绍和实例应用(转)
    Eclipse+PyDev 安装和配置(转)
    [Python]网络爬虫(二):利用urllib2通过指定的URL抓取网页内容(转)
  • 原文地址:https://www.cnblogs.com/lijunjiang2015/p/8060403.html
Copyright © 2020-2023  润新知