Python中的进程线程
文章目录
- 前言
- 多进程与多线程
- 基本概念
- 多进程
- multiprocessing 类对象
- 进程池
- subprocess模块
- 进程间通信
- 多线程
- threading实现线程操作
- 线程共享所有变量
- 线程锁
- 参考资料
前言
又花了点时间学习了一下Python中的多线程与多进程的知识点,梳理一下供复习参考
多进程与多线程
基本概念
进程指的是程序的一次执行,它是系统资源分配的单位,不同进程间的资源互相独立,但是系统开销较大
线程是进程的执行单元,它是CPU调度的基本单位,线程能够共享进程的资源,它的优点是效率高,缺点是会影响所在的进程
多进程
multiprocessing 类对象
Python中的多进程常用multiprocessing库实现,支持跨平台的多进程操作,一个实例如下:
from multiprocessing import Process
import os
import time
def run_proc(name):print('子进程 %s PID: %s 已经启动...' % (name,os.getpid()))time.sleep(5)print('子进程 %s PID: %s 终止...' % (name,os.getpid()))if __name__ == '__main__':print('父进程PID: %s' % (os.getpid()))p=Process(target=run_proc,args=('test',))print('子进程即将启动...')p.start() #启动进程,并调用该子进程中的p.run()p.join() #阻塞当前所在进程,等待所有进程退出 #尝试注释此行观察程序执行变化print('主进程终止...')
- 一个Processs对象就代表一个进程对象,传入的函数名及参数作为进程对象的参数
- 使用start方法启动进程对象,默认调用子进程的run()方法
- join方法表示等待进程结束,此实例中用p.join()表示主进程阻塞,等待子进程执行推出后再继续执行
进程池
利用进程池运行进程的实例如下:
from multiprocessing import Pool
import os,time,randomdef long_time_task(name):print('子进程 %s 启动, PID: %s' % (name, os.getpid()) )stime=time.time()# time.sleep(random.random()*3)time.sleep(1)etime=time.time()print('子进程 %s 运行结束,耗时: %f' % (name,(etime-stime)))if __name__ == '__main__':print('主进程启动,PID:',os.getpid())stime=time.time()p=Pool(2) #Pool()中的参数表示最多能够同时运行几个进程,其余进程需要等到已运行进程结束后才能运行for i in range(6):p.apply_async(long_time_task,args=(i,))print('等待所有子进程运行结束...')p.close()p.join()etime=time.time()print('所有子进程运行结束,共耗时:',(etime-stime))
执行结果:
解释:
- 每次同时运行两个进程,每个进程执行时间约1秒,共有6个进程,因此执行时间共为3秒
- 如果注释掉 join()的话主进程会直接结束,看不到子进程的输出
subprocess模块
subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。
其中的subprocess.call()则可以调用windows系统cmd命令行执行额外的命令。
import subprocessprint('利用subprocess查询DNS...')
r=subprocess.call(['nslookup','baidu.com'])
print('返回状态码',r)
执行结果
解释:利用subprocess.call()类似于我们开启了一个新的命令窗口(新的进程),输入call()方法的参数,同时将命令执行结果的输出返回到当前进程的输出
进程间通信
multiprocessing模块提供了队列、管道等方式帮助进程之间交换数据
以下例子创建了两个进程,read进程向队列中读取数据,write进程向队列中写入数据
from multiprocessing import Process,Queue
import os,time,randomdef write(q):print('write进程启动,PID:',os.getpid())for value in ['A','B','C','D']:print('将',value,'放入队列')q.put(value)time.sleep(1)def read(q):print('read进程启动,PID:',os.getpid())while True:value=q.get()print('从队列中取出',value)pass
执行结果:
多线程
- Python支持真正的多线程
- 通常用_thread和threading两个模块实现Python多线程,后者更为常用
- 线程执行的目标是函数,可以为线程命名
threading实现线程操作
import time,threadingdef lp():print('线程',threading.current_thread().name,'正在运行')for i in range(3):print('线程进入第',i+1,'次循环')time.sleep(1)print('线程',threading.current_thread().name,'终止')print('线程',threading.current_thread().name,'正在运行')
t=threading.Thread(target=lp,name='子线程')
t.start()
t.join()
print('线程',threading.current_thread().name,'终止')
执行结果
线程共享所有变量
以下是一个简单的例子,利用add和sub线程对共享变量进行修改
import time,threading
share=1000
def add():global shareshare+=5print('线程',threading.current_thread().name,'正在运行,变量share自增, share:',share)time.sleep(1)def sub():global shareshare-=2print('线程',threading.current_thread().name,'正在运行,变量share自减, share:',share)time.sleep(1)t1=threading.Thread(target=add,name='add')
t2=threading.Thread(target=sub,name='sub')
t1.start()
t2.start()
t1.join()
t2.join()
print('share:',share)
执行结果:
线程锁
让我们尝试修改一下上面的例子,add和sub线程随机修改三次共享变量share,没有线程锁时将出现混乱,我们无法预测哪个线程先对share变量进行修改,程序每次运行的结果可能会有不一样:
import time,threading,randomshare=1000
lock=threading.Lock()def add():global share#随机自增三次for i in range(3):share+=random.randint(1,10)print('线程',threading.current_thread().name,'正在运行,变量share随机自增, share:',share)time.sleep(random.random())def sub():global share#随机自减三次for i in range(3):share-=random.randint(1,10)print('线程',threading.current_thread().name,'正在运行,变量share随机自减, share:',share)time.sleep(random.random())t1=threading.Thread(target=add,name='add')
t2=threading.Thread(target=sub,name='sub')
t1.start()
t2.start()
t1.join()
t2.join()
print('share:',share)
运行结果:
加入线程锁之后,就可以等到某个线程执行结束后再执行另一个线程,不会出现交替执行的情况
import time,threading,randomshare=1000
lock=threading.Lock()def add():global share#随机自增三次try:lock.acquire()for i in range(3):share+=random.randint(1,10)print('线程',threading.current_thread().name,'正在运行,变量share随机自增, share:',share)time.sleep(random.random())finally:lock.release()def sub():global share#随机自减三次try:lock.acquire()for i in range(3):share-=random.randint(1,10)print('线程',threading.current_thread().name,'正在运行,变量share随机自增, share:',share)time.sleep(random.random())finally:lock.release()t1=threading.Thread(target=add,name='add')
t2=threading.Thread(target=sub,name='sub')
t1.start()
t2.start()
t1.join()
t2.join()
print('share:',share)
执行结果:
参考资料
Python正则表达式
Python多进程与多线程
subprocess.call()
相关文章:

Python中的进程线程
文章目录前言多进程与多线程基本概念多进程multiprocessing 类对象进程池subprocess模块进程间通信多线程threading实现线程操作线程共享所有变量线程锁参考资料前言 又花了点时间学习了一下Python中的多线程与多进程的知识点,梳理一下供复习参考 多进程与多线程 …...

python(8):使用conda update更新conda后,anaconda所有环境崩溃----问题没有解决,不要轻易更新conda
文章目录0. 教训1. 问题:使用conda update更新conda后,anaconda所有环境崩溃1.1 问题描述1.2 我搜索到的全网最相关的问题----也没有解决3 尝试流程记录3.1 重新安装pip3.2 解决anaconda编译问题----没成功0. 教训 (1) 不要轻易使用conda update更新conda----我遇到…...

c++11 标准模板(STL)(std::multimap)(四)
定义于头文件 <map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class multimap;(1)namespace pmr { template <class Key, class T…...
乐观锁及悲观锁
目录 1.乐观锁 (1).定义 (2).大体流程 (3).实现 (4).总结 2.悲观锁 (1).定义 (2).大体流程 (3).实现 (4).缺点 (5).总结 1.乐观锁 (1).定义 乐观锁在操作数据时非常乐观,认为别的线程不会同时修改数据所以不会上锁,但是在更新的时候会判断一…...

常见的锁策略
注意: 接下来讲解的锁策略不仅仅是局限于 Java . 任何和 "锁" 相关的话题, 都可能会涉及到以下内容. 这些特性主要是给锁的实现者来参考的.普通的程序猿也需要了解一些, 对于合理的使用锁也是有很大帮助的. 1.乐观锁 vs 悲观锁 悲观锁: (认为出现锁冲…...

springboot学习(八十) springboot中使用Log4j2记录分布式链路日志
在分布式环境中一般统一收集日志,但是在并发大时不好定位问题,大量的日志导致无法找出日志的链路关系。 可以为每一个请求分配一个traceId,记录日志时,记录此traceId,从网关开始,依次将traceId记录到请求头…...
10种ADC软件滤波方法及程序
10种ADC软件滤波方法及程序一、10种ADC软件滤波方法1、限幅滤波法(又称程序判断滤波法)2、中位值滤波法3、算术平均滤波法4、递推平均滤波法(又称滑动平均滤波法)5、中位值平均滤波法(又称防脉冲干扰平均滤波法&#x…...

第五章:Windows server加域
加入AD域:教学视频:https://www.bilibili.com/video/BV1xM4y1D7oL/?spm_id_from333.999.0.0首先我们选择一个干净的,也就是新建的没动过的Windows server虚拟机。我们将DNS改成域的ip地址,还要保证它们之间能ping的通,…...
Elasticsearch:获取 nested 类型数组中的所有元素
在我之前的文章 “Elasticsearch: object 及 nested 数据类型” 对 nested 数据类型做了一个比较详细的介绍。在实际使用中,你在构建查询时肯定会遇到一些问题。根据官方文档介绍,nested 类型字段在隐藏数组中索引其每个项目,这允许独立于索引…...
English Learning - Day53 作业打卡 2023.2.7 周二
English Learning - Day53 作业打卡 2023.2.7 周二引言1. 我必须承认,我之前学习没你用功。have to VS must2. 这跟我想得一样简单。3. 生活并不像它看上去那么顺风顺水,但也不会像我们想象得那么难。Look VS seem4. 你比去年高多了。5. 你关心你的工作胜…...

SpringMVC--注解配置SpringMVC、SpringMVC执行流程
注解配置SpringMVC 使用配置类和注解代替web.xml和SpringMVC配置文件的功能 创建初始化类,代替web.xml 在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类, 如果找到的话就用它来配置Servle…...

JavaScript中数组常用的方法
文章目录前言常用数组方法1、 join( )2、push()与 pop()3、shift()与 unshift()4、sort()5、reverse()6、slice(ÿ…...
ModuleNotFoundError: No module named ‘pip‘
项目场景:pip 错误 Traceback (most recent call last): File "E:\KaiFa\Python\Python38\lib\runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "E:\KaiFa\Python\Python38\lib\runpy.py&qu…...
ROS2 入门应用 发布和订阅(C++)
ROS2 入门应用 发布和订阅(C)1. 创建功能包2. 创建源文件2.1. 话题发布2.2. 话题订阅3. 添加依赖关系4. 添加编译信息4.1. 添加搜索库4.2. 增加可执行文件4.3. 增加可执行文件位置5. 编译和运行1. 创建功能包 在《ROS2 入门应用 工作空间》中已创建和加…...

XSS漏洞,通过XSS实现网页挂马
**今天讲下通过XSS实现网页挂马~*,目的是了解安全方面知识,提升生活网络中辨别度 原理: 实验分为两部分: 1、通过Kali linux,利用MS14_064漏洞,制作一个木马服务器。存在该漏洞的用户一旦通过浏览器访问木…...

家政服务小程序实战教程09-图文卡片
小程序还有一类需求就是展示服务的列表,我们这里用图文卡片组件来实现,我们先要添加一个标题,使用网格布局来实现 第一列添加一个文本组件,第二列添加一个图标组件 修改文本组件的文本内容,设置外边距 设置第二列的样式…...

国内唯一一部在CentOS下正确编译安装和使用RediSearch的教程
开篇 Redis6开始增加了诸多激动人心的模块,特别是:RedisJSON和RediSearch。这两个模块已经完全成熟了。它们可以直接使用我们的生产上的Redis服务器来做全文搜索(二级搜索)以取得更廉价的硬件成本、同时在效率上竟然超过了Elastic…...

前端对于深拷贝和浅拷贝的应用和思考
浅拷贝 浅拷贝 : 浅拷贝是指对基本类型的值拷贝,以及对对象类型的地址拷贝。它是将数据中所有的数据引用下来,依旧指向同一个存放地址,拷贝之后的数据修改之后,也会影响到原数据的中的对象数据。最简单直接的浅拷贝就…...

Java基础常见面试题(三)
String 字符型常量和字符串常量的区别? 形式上: 字符常量是单引号引起的一个字符,字符串常量是双引号引起的若干个字符; 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算;字符串常量代表一个地址值…...

C++设计模式(13)——装饰模式
亦称: 装饰者模式、装饰器模式、Wrapper、Decorator 意图 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 问题 假设你正在开发一个提供通知功能的库, 其他程序可使用它向用户发…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...

智警杯备赛--excel模块
数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中,点击确定 这是最终结果,但是由于环境启不了,这里用的是自己的excel,真实的环境中的excel根据实训…...

【动态规划】B4336 [中山市赛 2023] 永别|普及+
B4336 [中山市赛 2023] 永别 题目描述 你做了一个梦,梦里有一个字符串,这个字符串无论正着读还是倒着读都是一样的,例如: a b c b a \tt abcba abcba 就符合这个条件。 但是你醒来时不记得梦中的字符串是什么,只记得…...
TMC2226超静音步进电机驱动控制模块
目前已经使用TMC2226量产超过20K,发现在静音方面做的还是很不错。 一、TMC2226管脚定义说明 二、原理图及下载地址 一、TMC2226管脚定义说明 引脚编号类型功能OB11电机线圈 B 输出 1BRB2线圈 B 的检测电阻连接端。将检测电阻靠近该引脚连接到地。使用内部检测电阻时,将此引…...