python 多进程锁Lock和共享内存

简介: 多进程锁lock = multiprocessing.Lock() 创建一个锁lock.acquire() 获取锁lock.release() 释放锁with lock: 自动获取、释放锁 类似于 with open() as f:特点:谁先抢到锁谁先执行,等到该进程执行完成后,其...

多进程锁

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

相关文章
|
1月前
|
安全 Java 数据库连接
一把锁的两种承诺:synchronized如何同时保证互斥与内存可见性?
临界区指多线程中访问共享资源的代码段,需通过互斥机制防止数据不一致与竞态条件。Java用`synchronized`实现同步,保证同一时刻仅一个线程执行临界区代码,并借助happens-before规则确保内存可见性与操作顺序,从而保障线程安全。
126 11
|
2月前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
227 2
|
3月前
|
传感器 数据采集 监控
Python生成器与迭代器:从内存优化到协程调度的深度实践
简介:本文深入解析Python迭代器与生成器的原理及应用,涵盖内存优化技巧、底层协议实现、生成器通信机制及异步编程场景。通过实例讲解如何高效处理大文件、构建数据流水线,并对比不同迭代方式的性能特点,助你编写低内存、高效率的Python代码。
198 0
|
10月前
|
消息中间件 存储 网络协议
从零开始掌握进程间通信:管道、信号、消息队列、共享内存大揭秘
本文详细介绍了进程间通信(IPC)的六种主要方式:管道、信号、消息队列、共享内存、信号量和套接字。每种方式都有其特点和适用场景,如管道适用于父子进程间的通信,消息队列能传递结构化数据,共享内存提供高速数据交换,信号量用于同步控制,套接字支持跨网络通信。通过对比和分析,帮助读者理解并选择合适的IPC机制,以提高系统性能和可靠性。
1335 14
|
4月前
|
监控 编译器 Python
如何利用Python杀进程并保持驻留后台检测
本教程介绍如何使用Python编写进程监控与杀进程脚本,结合psutil库实现后台驻留、定时检测并强制终止指定进程。内容涵盖基础杀进程、多进程处理、自动退出机制、管理员权限启动及图形界面设计,并提供将脚本打包为exe的方法,适用于需持续清理顽固进程的场景。
|
6月前
|
数据可视化 Linux iOS开发
Python测量CPU和内存使用率
这些示例帮助您了解如何在Python中测量CPU和内存使用率。根据需要,可以进一步完善这些示例,例如可视化结果或限制程序在特定范围内的资源占用。
269 22
|
9月前
|
监控 Java 计算机视觉
Python图像处理中的内存泄漏问题:原因、检测与解决方案
在Python图像处理中,内存泄漏是常见问题,尤其在处理大图像时。本文探讨了内存泄漏的原因(如大图像数据、循环引用、外部库使用等),并介绍了检测工具(如memory_profiler、objgraph、tracemalloc)和解决方法(如显式释放资源、避免循环引用、选择良好内存管理的库)。通过具体代码示例,帮助开发者有效应对内存泄漏挑战。
465 1
|
10月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
727 20
|
9月前
|
数据采集 Java 数据处理
Python实用技巧:轻松驾驭多线程与多进程,加速任务执行
在Python编程中,多线程和多进程是提升程序效率的关键工具。多线程适用于I/O密集型任务,如文件读写、网络请求;多进程则适合CPU密集型任务,如科学计算、图像处理。本文详细介绍这两种并发编程方式的基本用法及应用场景,并通过实例代码展示如何使用threading、multiprocessing模块及线程池、进程池来优化程序性能。结合实际案例,帮助读者掌握并发编程技巧,提高程序执行速度和资源利用率。
457 0
|
11月前
|
Linux 调度 C语言
深入理解操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅,从进程管理的基本概念出发,逐步探索到内存管理的高级技巧。我们将通过实际代码示例,揭示操作系统如何高效地调度和优化资源,确保系统稳定运行。无论你是初学者还是有一定基础的开发者,这篇文章都将为你打开一扇了解操作系统深层工作原理的大门。
152 4

推荐镜像

更多