当前位置: 首页 > news >正文

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).定义 乐观锁在操作数据时非常乐观&#xff0c;认为别的线程不会同时修改数据所以不会上锁&#xff0c;但是在更新的时候会判断一…...

常见的锁策略

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

springboot学习(八十) springboot中使用Log4j2记录分布式链路日志

在分布式环境中一般统一收集日志&#xff0c;但是在并发大时不好定位问题&#xff0c;大量的日志导致无法找出日志的链路关系。 可以为每一个请求分配一个traceId&#xff0c;记录日志时&#xff0c;记录此traceId&#xff0c;从网关开始&#xff0c;依次将traceId记录到请求头…...

10种ADC软件滤波方法及程序

10种ADC软件滤波方法及程序一、10种ADC软件滤波方法1、限幅滤波法&#xff08;又称程序判断滤波法&#xff09;2、中位值滤波法3、算术平均滤波法4、递推平均滤波法&#xff08;又称滑动平均滤波法&#xff09;5、中位值平均滤波法&#xff08;又称防脉冲干扰平均滤波法&#x…...

第五章:Windows server加域

加入AD域&#xff1a;教学视频&#xff1a;https://www.bilibili.com/video/BV1xM4y1D7oL/?spm_id_from333.999.0.0首先我们选择一个干净的&#xff0c;也就是新建的没动过的Windows server虚拟机。我们将DNS改成域的ip地址&#xff0c;还要保证它们之间能ping的通&#xff0c…...

Elasticsearch:获取 nested 类型数组中的所有元素

在我之前的文章 “Elasticsearch: object 及 nested 数据类型” 对 nested 数据类型做了一个比较详细的介绍。在实际使用中&#xff0c;你在构建查询时肯定会遇到一些问题。根据官方文档介绍&#xff0c;nested 类型字段在隐藏数组中索引其每个项目&#xff0c;这允许独立于索引…...

English Learning - Day53 作业打卡 2023.2.7 周二

English Learning - Day53 作业打卡 2023.2.7 周二引言1. 我必须承认&#xff0c;我之前学习没你用功。have to VS must2. 这跟我想得一样简单。3. 生活并不像它看上去那么顺风顺水&#xff0c;但也不会像我们想象得那么难。Look VS seem4. 你比去年高多了。5. 你关心你的工作胜…...

SpringMVC--注解配置SpringMVC、SpringMVC执行流程

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

JavaScript中数组常用的方法

文章目录前言常用数组方法1、 join( )2、push&#xff08;&#xff09;与 pop&#xff08;&#xff09;3、shift&#xff08;&#xff09;与 unshift&#xff08;&#xff09;4、sort&#xff08;&#xff09;5、reverse&#xff08;&#xff09;6、slice&#xff08;&#xff…...

ModuleNotFoundError: No module named ‘pip‘

项目场景&#xff1a;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 入门应用 发布和订阅&#xff08;C&#xff09;1. 创建功能包2. 创建源文件2.1. 话题发布2.2. 话题订阅3. 添加依赖关系4. 添加编译信息4.1. 添加搜索库4.2. 增加可执行文件4.3. 增加可执行文件位置5. 编译和运行1. 创建功能包 在《ROS2 入门应用 工作空间》中已创建和加…...

XSS漏洞,通过XSS实现网页挂马

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

家政服务小程序实战教程09-图文卡片

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

国内唯一一部在CentOS下正确编译安装和使用RediSearch的教程

开篇 Redis6开始增加了诸多激动人心的模块&#xff0c;特别是&#xff1a;RedisJSON和RediSearch。这两个模块已经完全成熟了。它们可以直接使用我们的生产上的Redis服务器来做全文搜索&#xff08;二级搜索&#xff09;以取得更廉价的硬件成本、同时在效率上竟然超过了Elastic…...

前端对于深拷贝和浅拷贝的应用和思考

浅拷贝 浅拷贝 &#xff1a; 浅拷贝是指对基本类型的值拷贝&#xff0c;以及对对象类型的地址拷贝。它是将数据中所有的数据引用下来&#xff0c;依旧指向同一个存放地址&#xff0c;拷贝之后的数据修改之后&#xff0c;也会影响到原数据的中的对象数据。最简单直接的浅拷贝就…...

Java基础常见面试题(三)

String 字符型常量和字符串常量的区别&#xff1f; 形式上: 字符常量是单引号引起的一个字符&#xff0c;字符串常量是双引号引起的若干个字符&#xff1b; 含义上: 字符常量相当于一个整型值( ASCII 值)&#xff0c;可以参加表达式运算&#xff1b;字符串常量代表一个地址值…...

C++设计模式(13)——装饰模式

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

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...