有人问,Python中所谓的同步异步编程到底是什么呀?
同步异步其实很好理解,比如你去某站下载视频,有两种情况,分别代表同步和异步。
1、点击下载视频A,等A下载好后,再点击下载视频B,以此类推下载所有视频。
2、点击下载视频A,不管是否下载好,然后立即点击下载视频B,各下载任务同时进行中,以此类推下载所有视频。
第1种是同步,是排队执行,只有前一个任务完成后才执行后一个任务。
第2种是异步,边干边等,利用等待时间去处理其他任务,可以多个任务灵活并行。
如果不考虑网速带宽,第1种效率很明显会低于第2种。
下面咱们用Python代码测试下,首先是同步执行下载任务。
# 测试:使用同步代码
import time
def dowload(name):
print(f"{name}开始下载")
time.sleep(2) # 模拟视频下载耗时
print(f"{name}下载完成")
begin = time.time()
dowload("视频A") # 必须等A下载完...
dowload("视频B") # ...才会开始下载视频B
end = time.time()
print("用时{}秒".format(end - begin))
结果如下,用时4秒+。
因为同步会阻塞,视频A下载好了才开始下载视频B。
接下来使用异步编程来实现同样的任务。
这里注意下,Python中使用异步编程,需要async/await特殊语法。
# 测试:使用异步代码
import asyncio
import time
async def dowload(name):
print(f"{name}开始下载")
await asyncio.sleep(2) # 非阻塞等待
print(f"{name}下载完成")
async def main():
await asyncio.gather(
dowload("视频A"),
dowload("视频B")
)
begin = time.time()
asyncio.run(main())
end = time.time()
print("用时{}秒".format(end - begin))
结果如下,只用了2秒+。
异步不用等待A下载完成,直接下载B,两个同时进行,不存在等待阻塞。
这下就很好理解同步和异步的原理和区别了,同步是排队干活,异步并不是同时干很多活,而是灵活的分配精力在多个任务上,不因为等待而耗费时间。
那同步和异步的使用场景有哪些呢?
同步适合那些严格依赖执行顺序的任务,比如订单任务(下单->发货)、转账任务(扣款->入账)等,还有CPU计算密集型任务,像是数学计算、图像处理等。
异步则适合那些IO操作密集型和高并发的任务,比如给用户发消息、web网页请求、文件读写、文件下载和上传等,这些任务的特点是需要等待时间,异步能提高任务执行效率。
所以说同步异步适合不同的业务场景,并不存在好坏对错之分。
下表是一些场景和案例对比,供参考。