Python异步编程与并行编程
并发和并行
线程级并行
指令级并行
在较低的抽象层次上,现代处理器可以同时执行多条指令的属性称为指令级并行
流水线(pipelining)
超标量(superscalar)处理器
单指令、多数据并行
在最低层次上,许多现代处理器拥有特殊的硬件,允许一条指令产生多个可以并行执行的操作,这种方式称为单指令、多数据,即SIMD 并行。硬件结构决定的。
同步synchronous,异步 asynchronous,并发 concurrent,并行parall
-
并行是真同时,并发是假同时
-
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;同步是一种依赖关系。不发晚安就不睡觉
-
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。异步是互相独立,想到什么就给你发消息
进程process,线程thread,协程
进程是资源分配的单位,线程是
协程是用户自己管理的异步编程工具
python并发编程
python多进程
python的多进程是真并行,每个进程有自己的解释器(GIL)
The multiprocessing module allows you to create multiple processes, each of them with its own Python interpreter. For this reason, Python multiprocessing accomplishes process-based parallelism.
优质回答:Multiprocessing vs Threading in Python
https://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python
python多线程
python的多线程是并发,多个线程实际上共享一个GIL
threading模块使用线程,multiprocessing模块使用进程。不同的是,线程运行在同一个内存空间,而进程拥有独立的内存。这使得在进程之间共享对象变得困难。另外一方面,由于线程使用相同的内存,因此必须采取预防措施,否则两个线程将同时写入同一内存。这就是全局解释器锁GIL的用途。
来保证python的很多方法(如list.append)是线程安全的
生成进程比生成线程慢一点。
异步和多线程有什么本质区别?
异步是减少任务之间的等待(取消任务的依赖关系),多线程是多几个工人来做任务
多线程就是实现异步的一个方式。 异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。 所以本质上,异步和多线程并不是一个同等关系,异步是最终目的,多线程只是实现异步的一种手段。
异步方法与前两个概念(并发,并行)没有直接关系,异步用于给用户呈现一种貌似同时进行任务处理的印象
从用户的角度来看,它看起来像是多任务处理multitasking ,但它不是。
python的协程机制
参考网站:
https://www.lylinux.net/article/2019/6/9/57.html#asynciogatherasynciowait
廖雪峰教程
知乎python协程好文
刘江的教程(似乎还有Django)
python官方文档
asyncio
宏观,asyncio在做什么事情?
nothing but 让等待时间变短
因为python的全局解释器锁GIL使得无法实现真正的并发,一个时间点,一段代码只能产生一个线程
什么时候用?
只有你的代码里有很多需要多个任务等待的时候才需要用协程
否则不会提升性能
比如网络编程很需要等待,就适合用协程
具体的语言机制,语法,设定
coroutine
coroutine function
python里面所有以async def开头的东西都是coroutine function
所有的coroutine function调用的时候并不会执行函数里的代码,只会返回一个coroutine object
那怎么样才可以执行coroutine呢?
用入口函数asyncio.run(),这个函数的参数是一个coroutine object
他会做两件事情:
- 建立起一个event loop开始掌管一切
- 把这个coroutine变成这个event loop里的第一个task开始运行
asyncio.run()函数使我们从synchronize模式变到asynchronize模式的入口
coroutine object
上面有eventloop是大脑
下面是若干可执行的task
task没有办法控制event loop去执行某一个task,它只能告诉event loop说我在等这个task,最终由event loop决定要运行哪个task
event loop一旦开始运行,就必须task显示地把控制权交还给event loop
交还控制权的方式有两种:
- await
- 函数运行完毕
coroutine要变成task才可以被event loop运行
什么时候coroutine被隐式的变成了task:
- 直接await
- gather
放进去的都是coroutine,但是它们会把coroutine们偷偷变成tasks
await语法
gather语法
码农高天的教程
await机理
如何实现异步的?如何实现那些依赖的?为什么它那么聪明知道要先运行谁呢?
numba模块
numba可以越过虚拟机把一个函数的字节码变成另一种机器指令,这是JIT即时编译的一种,可以大幅提高python计算密集程序的效率,一般情况下由于GIL的存在,python处理计算密集程序的效率是受限制的。而numba可以解决这个问题。
https://lulaoshi.info/gpu/python-cuda/numba.html#numba的使用场景
numba.jit()装饰器不能直接装饰类方法的问题
python里面的函数和方法有什么区别?
类型分别是method和function,class和object在python中其实都是对象
异步编程与后端开发
流畅的Python讲了不少,这个异步编程asyncio实际上在后端开发里面有很大的实际意义。有利用asyncio实现高并发TCP服务器的编程实例,自己再去网上找一个基于线程threading库的实现对比体会。这样一举拿下了socket网络编程、并发/并行编程、多路复用IO什么的,也可以熟悉进程、线程。协程的概念,在使用threading库和asyncio库中加强理解
利用asyncio实现高并发TCP服务器、
利用threading多线程实现TCP服务器,与asyncio的实现对比
python多线程是假的为啥还要用
Python多线程相当于单核多线程,多线程有两个好处:CPU并行,IO并行,
Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?