今天你早餐要吃煎蛋+烤面包,为了节省时间,我们将每道菜同比缩小至秒。
假设煎蛋需要5s钟,烤面包需要3秒钟,你会怎么做。
一、厨房新手:一次只做一个菜
import time
def fry_eggs():
print("开始煎蛋...")
time.sleep(5)
print("煎蛋结束")
def toast():
print("开始烤面包...")
time.sleep(3)
print("烤面包结束")
if __name__ == "__main__":
begin_time = time.time()
//先煎蛋
fry_eggs()
//再烤面包
toast()
end_time = time.time()
//历时为煎蛋的时间+烤面包的时间
print("总耗时%.2f秒" % (end_time - begin_time))
我们通常会先煎蛋,在烤面包,历时为煎蛋+烤面包的时间总和,应该为8s。
而这对于没有依赖关系的任务,保持一次只做一件事,就是同步编程。
二、厨房大佬:同时开锅,游刃有余
import asyncio
import time
async def fry_eggs():
print("开始煎蛋...")
await asyncio.sleep(5) # 改成异步 sleep
print("煎蛋结束")
async def toast():
print("开始烤面包...")
await asyncio.sleep(3) # 改成异步 sleep
print("烤面包结束")
async def main():
begin_time = time.time()
await asyncio.gather(fry_eggs(), toast())
end_time = time.time()
print("总耗时%.2f秒" % (end_time - begin_time))
if __name__ == "__main__":
asyncio.run(main())
由于是串行的,所以应该为最长任务的时间5s。
而这对于没有依赖关系的任务,多个任务并行做,就是异步编程。
三、对比总结
特点 | 同步编程 | 异步编程 |
---|---|---|
执行方式 | 按顺序执行 | 并发执行不阻塞 |
资源占用 | 简单高效(无调度开销) | 需要事件循环管理 |
使用场景 | 逻辑简单、顺序明确 | I/O 密集型任务、高并发场景 |
编写难度 | 简单直观 | 需理解协程、Event Loop等 |
异步很像项目管理中关键路径,当需要时间最长的任务完成时,所有任务才能完成。
因此很多时间我们在可以选择的情况下,根据项目实际情况选择“单兵作战”或“团队协作”。
因为在管理中,一开始人月神话一般是有用的。