多进程锁

  • 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() 方法会阻塞已调用进程锁的进程

python 多进程锁Lock和共享内存的更多相关文章

  1. python多线程锁lock/Rlock/BoundedSemaphore/Condition/Event

    import time import threading lock = threading.RLock() n = 10 def task(arg): # 加锁,此区域的代码同一时刻只能有一个线程执行 ...

  2. python 多进程数据交互及共享

    多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最 ...

  3. python多进程总结

    概述 由于python中全局解释器锁(GIL)的存在,所以python多线程并不能有效利用CPU多核的性能(相当于单核并发)实现多线程多核并行,所以在对CPU密集型的程序时处理效率较低,反而对IO密集 ...

  4. qt 共享内存(QSharedMemory)

    ——————————————————写入部分—————————————————— (本次程序基于控制台程序) 首先 使用共享内存得召唤一下: #include <QSharedMemory> ...

  5. Nginx 进程间如何共享内存

    L:37 Nginx 针对多进程用的是自旋锁(占用共享内存时间比较短的情况下否则可能会影响性能)注:自旋锁是不停的请求共享内存 而原先的信号量是等待占用者释放后通知等待的进程

  6. [转]WINDOW进程间数据通讯以及共享内存

    1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...

  7. win32下进程间通信——共享内存

    一.引言     在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换 ...

  8. Windows进程间共享内存通信实例

    Windows进程间共享内存通信实例 抄抄补补整出来 采用内存映射文件实现WIN32进程间的通讯:Windows中的内存映射文件的机制为我们高效地操作文件提供了一种途径,它允许我们在WIN32进程中保 ...

  9. linux编程之共享内存

    linux 进程间通信(IPC)包括3种机制:消息队列.信号量.共享内存.消息队列和信号量均是内核空间的系统对象,经由它们 的数据需要在内核和用户空间进行额外的数据拷贝:而共享内存和访问它的所有应用程 ...

随机推荐

  1. MySQL训练营01

    一.数据库基础知识: 1. 数据库(database):保存有组织的数据的容器(通常是一个或者一组文件) 2. 数据库管理系统(DBMS):数据库软件,外界通过DBMS来创建和操纵数据库,具体是什么, ...

  2. Mybatis实例教程整体说明

    什么是mybatisMyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或 ...

  3. PHP 用Symfony VarDumper Component 调试

    Symfony VarDumper 类似 php var_dump() 官方文档写的安装方法 : 按照步骤 就可以在 running any PHP code  时候使用了 In order to h ...

  4. RMQ问题+ST算法

    一.相关定义 RMQ问题 求给定区间的最值: 一般题目给定许多询问区间. 常见问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大 ...

  5. 浅谈C#中show和showDialog的区别

    [转载] A.WinForm中窗体显示  显示窗体可以有以下2种方法:  Form.ShowDialog方法 (窗体显示为模式窗体)  Form.Show方法 (窗体显示为无模式窗体) 2者具体区别如 ...

  6. pta编程(1-8)

    知识点:本次编程运用到的格式 #include<stdio.h> int main(void) { printf(); return 0; } 过程:1-3.没什么问题,就是注意字符的输入 ...

  7. HDU 2139 Calculate the formula

    http://acm.hdu.edu.cn/showproblem.php?pid=2139 Problem Description You just need to calculate the su ...

  8. combobox下拉框

    ----------------------------------------------combobox下拉框----------------------------------------- f ...

  9. ScrollBarsEnabled的使用

    在WinForm中通过WebBrowser获取网页,我想把WebBrowser的ScollBar去掉,我的网页不需要滚动条. 设置方法如下:单击WebBrowser设计页面,在属性页面有一个Scrol ...

  10. BZOJ3073 PA2011Journeys(线段树+bfs)

    线段树优化建图裸题.建两棵线段树,一棵表示入一棵表示出.对题中所给的边新建一个虚拟点,将两段区间拆成线段树上对应区间,出线段树中对应区间所表示的点向虚拟点连边权0的边,虚拟点向入线段树中对应区间所表示 ...