Python基础语法(多进程开发进程建数据共享进程锁进程池)

 Python基础语法文章导航:

  1. Python基础(01初识数据类型&变量)
  2. Python基础(02条件&循环语句)
  3. Python基础(03字符串格式化&运算符&进制&编码)
  4. Python基础(04 基础练习题)
  5. Python数据类型(day05整型&布尔类型&字符串类型)
  6. Python数据类型(06列表&元组)
  7. Python数据类型(07集合&字典&浮点型&None)
  8. Python文件操作01(自动化测试文件相关操作)
  9. Python函数入门(08函数定义&参数&返回值)

  10. Python文件操作02(自动化测试文件相关操作)

  11. Python函数(10生成器&内置函数&推导式)

  12. Python函数(11自定义模块&第三方模块&内置模块)

  13. Python函数(12时间处理&正则表达式)

  14. Python函数(13面向对象)

  15. Python面向对象(15成员&成员修饰符)

  16. Python函数(16进程和线程)

  17. Python基础语法(17多线程&线程锁&单例模式)

目录

一.多进程开发

1. 进程介绍

2. 常见功能

(1)p.start()

(2)p.join()

(3)p.daemon = 布尔值

(4)进程的名称的设置和获取

(5)自定义进程类,直接将线程需要做的事写到run方法中。

(6)CPU个数,程序一般创建多少个进程?(利用CPU多核优势)

二. 进程间数据的共享

1.共享

2.交换

(1)Queues

(2)Pipes

 3. 进程锁

4. 进程池


一.多进程开发

        进程是计算机中资源分配的最小单元;一个进程中可以有多个线程,同一个进程中的线程共享资源;进程与进程之间则是相互隔离

Python中通过多进程可以利用CPU的多核优势,计算密集型操作适用于多进程。

1. 进程介绍

import multiprocessingdef task(arg):passdef run():p1 = multiprocessing.Process(target=task, args=('XXX'), )#当前进程准备就绪,等待被CPU调度(工作单元其实是进程中的线程)p1.start()if __name__ == '__main__':run()

2. 常见功能

进程的常见方法:

(1)p.start()

  当前进程准备就绪,等待被CPU调度(工作单元其实是进程中的线程)。

(2)p.join()

  等待当前进程的任务执行完毕后再向下继续执行

def task(arg):time.sleep(2)print("执行中...")if __name__ == '__main__':multiprocessing.set_start_method("spawn")name=[]p1=multiprocessing.Process(target=task,args=('xxx',))p1.start()p1.join()time.sleep(2)print("继续执行...")
#执行中...
#继续执行...(过了2秒后出现)

(3)p.daemon = 布尔值

  守护进程(必须放在start之前)

  • p.daemon =True,设置为守护进程,主进程执行完毕后,子进程也自动关闭。

  • p.daemon =False,设置为非守护进程,主进程等待子进程,子进程执行完毕后,主进程才结束。

import multiprocessing
import timedef task(arg):time.sleep(2)print("执行中...")if __name__ == '__main__':multiprocessing.set_start_method("spawn")p1=multiprocessing.Process(target=task,args=('xxx',))p1.daemon=Truep1.start()time.sleep(2)print("继续执行...")
#继续执行...
import multiprocessing
import timedef task(arg):time.sleep(2)print("执行中...")if __name__ == '__main__':multiprocessing.set_start_method("spawn")p1=multiprocessing.Process(target=task,args=('xxx',))p1.daemon=Falsep1.start()time.sleep(2)print("继续执行...")
# 继续执行...
# 执行中...

(4)进程的名称的设置和获取

  • getpid:返回调用进程自身的进程ID。用于标识进程自身。

  • getppid:返回调用进程的父进程ID。用于标识创建调用进程的父进程。

  • multiprocessing.current_process().name:获取当前进程的名字

import multiprocessing
import os
import threading
import timedef func():time.sleep(3)def task(arg):for i in range(10):t=threading.Thread(target=func)t.start()#getpid、getppid分别获取当前进程的进程ID和当前进程的父进程ID。print(os.getpid(),os.getppid())print("线程个数",len(threading.enumerate()))time.sleep(2)print("当前进程的名称:",multiprocessing.current_process().name)if __name__ == '__main__':print(os.getpid())multiprocessing.set_start_method("spawn")p1=multiprocessing.Process(target=task,args=('xxx',))p1.name="哈哈哈哈哈"p1.start()print("继续执行...")
# 33756
# 继续执行...
# 22624 33756
# 线程个数 11
# 当前进程的名称: 哈哈哈哈哈备注:线程计算方法   有1(执行task的线程)+ 10(循环创建的线程)= 11个线程

(5)自定义进程类,直接将线程需要做的事写到run方法中。

import multiprocessing
class MyProcess(multiprocessing.Process):def run(self):print("执行此进程",self)if __name__ == '__main__':multiprocessing.set_start_method("spawn")p=MyProcess(args=('xxx',))p.start()print("继续执行...")
# 继续执行...
# 执行此进程 <MyProcess name='MyProcess-1' parent=29592 started>

(6)CPU个数,程序一般创建多少个进程?(利用CPU多核优势)

import multiprocessing
n=multiprocessing.cpu_count()
print(n)
#8
import multiprocessingdef task():passif __name__ == '__main__':count=multiprocessing.cpu_count()for i in range(count-1):p=multiprocessing.Process(target=task)p.start()

二. 进程间数据的共享

        进程是资源分配的最小单元,每个进程中都维护自己独立的数据,不共享

import multiprocessing
def task(data):data.append(666)if __name__ == '__main__':data_list=[]p=multiprocessing.Process(target=task,args=(data_list,))p.start()p.join()print("主进程:",data_list)
# 主进程: []

        如果想要让他们之间进行共享,则可以借助一些特殊的东西来实现。

1.共享

        multiprocessing.Value: 这是一个类,用来创建可以在不同进程间共享的值。它允许在多进程环境中安全地共享基本数据类型,如整数、浮点数等。

        在 Python 的 multiprocessing 模块中,常见的类型代码包括 'i'(整数)、'd'(浮点数)、'c'(字符,但通常用于 Array 而非 Value)等。

from multiprocessing import Value, Processdef func(n,m1,m2):n.value=888#将字符串 'a' 使用 utf-8 编码转换成了字节串 b'a',然后赋值给 m1.valuem1.value='a'.encode('utf-8')m2.value="武"if __name__ == '__main__':#这里的作用是使用Value类从multiprocessing模块创建一个可以在进程间共享的整数值#'i': 这个字符代表了要创建的共享变量的类型。在本例中,'i' 表示这是一个整数(integer)类型。# 666: 这是共享变量初始化的值。即这个可以在进程间共享的整数的初始值被设定为666。num=Value('i',666)#创建了一个新的共享内存变量 v1,类型指定为 'c',这通常表示一个字符类型v1=Value('c')#试图使用 'u' 类型创建一个 multiprocessing.Value 实例。但是,按照 multiprocessing.Value 的标准用法,类型代码 'u' 并不是直接支持的。v2=Value('u')p=Process(target=func,args=(num,v1,v2))p.start()p.join()print(num.value)print(v1.value)print(v2.value)
# 888
# b'a'
# 武
from multiprocessing import Process, Value, Array
def f(data_array):data_array[0] = 666if __name__ == '__main__':arr = Array('i', [11, 22, 33, 44]) # 数组:元素类型必须是int; 只能是这么几个数据。p = Process(target=f, args=(arr,))p.start()p.join()print(arr[:])
#[666, 22, 33, 44]

        利用 Python 的 multiprocessing 模块中的 Manager 类来创建一个管理器上下文。这个管理器允许您创建可在多个进程之间共享的容器,如列表、字典等。这种方式比直接使用 Value 或 Array 更灵活,尤其适合于需要共享复杂数据结构的场景。 

from multiprocessing import Process, Manager
def f(d, l):d[1] = '1'd['2'] = 2d[0.25] = Nonel.append(666)if __name__ == '__main__':with Manager() as manager:d = manager.dict()l = manager.list()p = Process(target=f, args=(d, l))p.start()p.join()print(d)print(l)
# {1: '1', '2': 2, 0.25: None}
# [666]

2.交换

(1)Queues

        使用 queue = multiprocessing.Queue() 这段代码时,创建一个线程或进程安全的队列,这个队列允许您在多个进程之间安全地传递数据,用于进程间通信的一个非常实用的数据结构。

        q.put(i) 表示正向这个队列中放入一个元素 i。这里 i 应该是一个在上下文中已经定义过的变量,意味着即使有多个进程同时尝试向队列中放入或获取数据,队列也能保证数据的正确性和完整性,不会引发冲突。

        一旦数据被放入队列,其他进程可以通过 q.get() 方法来取出这个数据。这是一种典型的“生产者-消费者”模型,其中一个进程(生产者)向队列中放入数据,另一个或多个进程(消费者)从队列中取出并处理数据。

import multiprocessing
def task(q):for i in range(10):q.put(i)if __name__ == '__main__':queue = multiprocessing.Queue()p = multiprocessing.Process(target=task, args=(queue,))p.start()p.join()print("主进程")print(queue.get())print(queue.get())print(queue.get())print(queue.get())print(queue.get())
# 主进程
# 0
# 1
# 2
# 3
# 4

(2)Pipes

import time
import multiprocessing
def task(conn):time.sleep(1)conn.send([111, 22, 33, 44])data = conn.recv() # 阻塞print("子进程接收:", data)time.sleep(2)if __name__ == '__main__':parent_conn, child_conn = multiprocessing.Pipe()p = multiprocessing.Process(target=task, args=(child_conn,))p.start()info = parent_conn.recv() # 阻塞print("主进程接收:", info)parent_conn.send(666)
# 主进程接收: [111, 22, 33, 44]
# 子进程接收: 666

 3. 进程锁

如果多个进程抢占式去做某些操作时候,为了防止操作出问题,可以通过进程锁来避免。

        lock = multiprocessing.RLock() 时,您初始化了一个可重入锁(Reentrant Lock),这是 multiprocessing 模块提供的一个同步原语。可重入锁允许同一个进程多次获得同一个锁,而不会发生死锁。这对于需要在多进程中保护共享资源的情况非常有用,尤其是当某个进程可能在其持有锁的期间再次请求同一把锁时。

        在每个进程中,对于那些需要互斥访问的资源,您需要在访问之前获取锁(lock.acquire()),并在访问完毕后释放锁(lock.release())

import time
import multiprocessingdef task(lock):print("开始")lock.acquire()# 假设文件中保存的内容就是一个值:10with open('f1.txt', mode='r', encoding='utf-8') as f:current_num = int(f.read())print("排队抢票了")time.sleep(0.5)current_num -= 1with open('f1.txt', mode='w', encoding='utf-8') as f:f.write(str(current_num))lock.release()if __name__ == '__main__':multiprocessing.set_start_method("spawn")lock = multiprocessing.RLock()  # 进程锁for i in range(10):p = multiprocessing.Process(target=task, args=(lock,))p.start()# spawn模式,需要特殊处理。time.sleep(7)
# 开始
# 排队抢票了
# 开始
# 开始
# 开始
# 开始
# 开始
# 开始
# 开始
# 开始
# 开始
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了

4. 进程池

注意:如果在进程池中要使用进程锁,则需要基于Manager中的Lock和RLock来实现。

        通过使用 manager = multiprocessing.Manager() 创建的管理器,您能够创建可在多个进程间共享的同步对象,如锁。因此,lock_object = manager.RLock() # Lock 正确地创建了一个可在进程池中各个进程间共享的可重入锁(RLock)。这解决了之前直接使用 multiprocessing.RLock() 时遇到的共享问题,因为 Manager 自动处理了跨进程的数据同步。

import time
import multiprocessing
from concurrent.futures.process import ProcessPoolExecutordef task(lock):print("开始")# lock.acquire()# lock.relase()with lock:# 假设文件中保存的内容就是一个值:10with open('f1.txt', mode='r', encoding='utf-8') as f:current_num = int(f.read())print("排队抢票了")time.sleep(1)current_num -= 1with open('f1.txt', mode='w', encoding='utf-8') as f:f.write(str(current_num))if __name__ == '__main__':pool = ProcessPoolExecutor()# lock_object = multiprocessing.RLock() # 不能使用manager = multiprocessing.Manager()lock_object = manager.RLock() # Lockfor i in range(10):pool.submit(task, lock_object)
# 开始
# 排队抢票了
# 开始
# 开始
# 开始
# 开始
# 开始
# 开始
# 开始
# 排队抢票了
# 开始
# 排队抢票了
# 开始
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了
# 排队抢票了

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1522617.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【MATLAB源码-第259期】基于matlab的64QAM调制解调锁相环环载波同步仿真,对比前后星座图,输出锁相环响应曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 概述 在现代数字通信系统中&#xff0c;为了提高频谱利用率和数据传输效率&#xff0c;经常采用多阶调制技术。64QAM&#xff08;64阶正交幅度调制&#xff09;便是其中的一种&#xff0c;它通过将数据映射到64个不同的复…

入门篇 LeetCode算法之旅启程 - 从零开始的编程进阶之路

你是否曾经在技术面试中因为算法题而汗流浃背?是否在日常编码中感觉自己的解决问题能力有待提高? 目录 LeetCode: 你的算法训练场为什么选择LeetCode?LeetCode平台使用指南1. 注册与登录2. 探索题库3. 解题过程4. 提交与反馈5. 学习与讨论6. 追踪进度7. 参与竞赛 制定你的…

【专项刷题】— 哈希表

1、两数之和 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 使用哈希表&#xff0c;将每次x target - nums[i]&#xff0c;查看哈希表中是否含有这个x值代码&#xff1a; public int[] twoSum(int[] nums, int target) {int n nums.length;Map<Integer,Inte…

坐牢第三十四天(c++)

一.作业 1.栈的手写 #include <iostream> using namespace std; // 封装一个栈 class stcak { private:int *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参构造函数stcak(int size);// 拷贝构造函数stcak(const s…

0903作业+思维导图

一、作业 1》多态的实现 1、代码 #include <iostream>using namespace std; //父类 class Person { public:string name;int age; public:Person(){}Person(string n,int a):name(n),age(a){}~Person(){}//纯虚函数virtual void show() 0; }; //子类1 class Stu:publ…

wsl下将Ubuntu从c盘移动到其他盘

一、概述 因为自己的C盘内存不足&#xff0c;加上之后需要在Ubuntu下面下载许多的内容和东西&#xff0c;需要将其移动到d盘上面&#xff0c;这样可以拥有更大的空间。这里记载了一下自己的操作过程。 二、具体步骤 &#xff08;一&#xff09;过程 1.查看当前系统中wsl分发版…

Haskell爬虫:连接管理与HTTP请求性能

爬虫技术作为数据抓取的重要手段&#xff0c;其效率和性能直接影响到数据获取的质量与速度。Haskell&#xff0c;作为一种纯函数式编程语言&#xff0c;以其强大的类型系统和并发处理能力&#xff0c;在构建高效爬虫方面展现出独特的优势。本文将探讨在Haskell中如何通过连接管…

技术Leader在训练团队思考力中的核心职责

引言 在技术驱动的行业中&#xff0c;技术团队的创新能力与问题解决能力往往直接关联到项目的成败与企业的竞争力。而这一切的基石&#xff0c;离不开团队中每一个成员的思考力。作为技术团队的领航者&#xff0c;技术Leader在培养和提升团队思考力方面扮演着至关重要的角色。…

【Godot4.3】基于纯绘图函数自定义的线框图控件

概述 同样是来自2023年7月份的一项实验性工作&#xff0c;基于纯绘图函数扩展的一套线框图控件。初期只实现了三个组件&#xff0c;矩形、占位框和垂直滚动条。 本文中的三个控件类已经经过了继承化的修改&#xff0c;使得代码更少。它们的继承关系如下&#xff1a; 源代码 W…

AI智能分析/智慧安防EasyCVR视频汇聚平台新版本(V3.6.0)播放鉴权与播放限制时长的区别介绍

随着科技的飞速发展&#xff0c;视频技术已成为现代社会不可或缺的一部分&#xff0c;广泛应用于安防监控、娱乐传播、在线教育、电商直播等多个领域。EasyCVR视频汇聚平台作为视频技术的佼佼者&#xff0c;不断推陈出新&#xff0c;通过功能更新迭代&#xff0c;为用户提供更加…

WEB服务与虚拟主机/IIS中间件部署

WWW&#xff08;庞大的信息系统&#xff09;是基于客户机/服务器⽅式的信息发现技术和超⽂本技术的综合。网页浏览器//网页服务器 WWW的构建基于三项核⼼技术&#xff1a; HTTP&#xff1a;超文本传输协议&#xff0c;⽤于在Web服务器和客户端之间传输数据。HTML&#xff1a;⽤…

SpringCloud开发实战(三):集成Eureka注册中心

目录 SpringCloud开发实战&#xff08;一&#xff09;&#xff1a;搭建SpringCloud框架 SpringCloud开发实战&#xff08;二&#xff09;&#xff1a;通过RestTemplate实现远程调用 Eureka简介 Eureka 是一个基于 Java 的开源技术&#xff0c;最广为人知的是作为 Netflix 开发…

ElasticSearch学习笔记(六)自动补全、拼音分词器、RabbitMQ实现数据同步

文章目录 前言11 自动补全11.1 拼音分词器11.2 自定义分词器11.3 自动补全查询 12 数据同步12.1 实现方案12.1.1 同步调用12.1.2 异步通知12.1.3 监听binlog 12.2 异步通知实现数据同步12.2.1 声明交换机和队列12.2.2 发送MQ消息12.2.3 接收MQ消息并操作ES 前言 ElasticSearch…

互联网职场说 | “400w能否实现‘躺平’的生活”

近年来&#xff0c;“躺平”一词在国内职场中频频出现&#xff0c;表达了许多年轻人对工作压力和生活负担的不满与逃避心理。 近日&#xff0c;一位网友在社交平台上提出了一个引人深思的问题&#xff1a;“400万可以躺平吗&#xff1f;有房有车无贷款。” 网友们也各抒己见&a…

GB/T28181规范和JT1078交通部标差异

技术背景 好多开发者区分不太清楚GB/T28181和JT1078规范&#xff0c;实际上&#xff0c;二者在规范定义、技术特点、过检认证以及应用场景等方面均存在显著差异。两者各有其适用领域和优势&#xff0c;但在某些特定场景下也可能需要相互协作以实现更全面的监控和管理。 规范定…

[学术论文] KBS期刊介绍及投稿流程学习笔记

该专栏主要是论文投稿的记录笔记&#xff0c;希望对初学者有所帮助&#xff0c;也希望大家论文都能命中。这篇文章主要介绍人工智能一区期刊Knowledge-Based Systems的投稿笔记&#xff0c;希望您喜欢&#xff01; 文章目录 一.期刊介绍二.投稿地址及模板1.投稿地址2.LaTex下载…

[工具使用]git

git fetch 获取远程仓库内容&#xff0c;但未合入本地仓库&#xff1b; git rebase 获取远程仓库内容&#xff0c;并更改基地合入本地仓库&#xff1b; 将master分支的内容合入feature分支&#xff1a; 当在feature分支上执行git rebase master时&#xff0c;git会从master…

Datawhale X 李宏毅苹果书 AI夏令营-深度学习进阶task3:批量归一化

1.批量归一化 如果误差表面很崎岖&#xff0c;它比较难训练。批量归一化&#xff08;Batch Normalization&#xff0c;BN&#xff09;就是其中一个“把山铲平”的想法 如图 所示&#xff0c;假设两个参数对损失的斜率差别非常大&#xff0c;在 w1 这个方向上面&#xff0c;斜…

聚观早报 | 苹果推出AI消除功能;比亚迪2024上半年营收

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 8月30日消息 苹果推出AI消除功能 比亚迪2024上半年营收 真我GT7 Pro渲染图曝光 苹果iPhone 16开始印度量产 故宫…

旗帜分田(华为od机考题)

一、题目 1.原题 从前有个村庄&#xff0c;村民们喜欢在各种田地上插上小旗子&#xff0c;旗子上标识了各种不同的数字。 某天集体村民决定将覆盖相同数字的最小矩阵形的土地的分配给为村里做出巨大贡献的村民&#xff0c; 请问&#xff0c;此次分配土地&#xff0c;做出贡献…