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() 方法会阻塞已调用进程锁的进程
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
8种创建Java线程的方式,你知道几个?
作者:唐彤 简介 创建线程,是多线程编程中最基本的操作,彤哥总结了一下,大概有8种创建线程的方式,你知道吗? 1.继承Thread类并重写run()方法 public class CreatingThread01 extends Thread { @Override public void run() { System.out.println(getName() + " is running"); } public static void main(String[] args) { new CreatingThread01().start(); new CreatingThread01().start(); new CreatingThread01().start(); new CreatingThread01().start(); } } 继承Thread类并重写run()方法,这种方式的弊端是一个类只能继承一个父类,如果这个类本身已经继承了其它类,就不能使用这种方式了。 2.实现Runnable接口 public class CreatingThread02 implements ...
- 下一篇
svelte教程(7)生命周期
onMount onMount将在组件首次呈现到DOM之后运行。除了onDestroy之外,生命周期函数不会在SSR期间运行,这意味着一旦组件挂在到DOM上,我们就可以避免在DOM构建之前获取到应在DOM构建以后加载的数据。 必须在逐渐初始化时调用生命周期函数,不能再setTimeout中调用。 如果onMount返回一个函数,则在销毁组件时将调用该函数。 <script> import { onMount } from 'svelte'; let photos = []; onMount(async () => { const res = await fetch(`https://jsonplaceholder.typicode.com/photos?_limit=20`); photos = await res.json(); }); </script> <style> .photos { width: 100%; display: grid; grid-template-columns: repeat(5, 1fr); grid-gap:...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Red5直播服务器,属于Java语言的直播服务器