御气篇-Day79 同步与异步的区别,什么是 IO 阻塞

0 次阅读 2026-10-20 09:23

📖 知识点

1. 同步(串行执行)

一件任务从头到尾做完,才会开始下一件。遇到等待操作,程序原地卡住等待,什么都不干 → 这就是IO 阻塞。IO = Input/Output,输入输出:网络请求、读取文件、数据库查询都属于 IO 操作。

生活比喻:同步:烧水的时候站在炉子旁边一动不动等着水烧开,水开了,再去洗菜。

2. 异步(协程并发)

遇到 IO 等待,不会原地死等,先放下当前任务,转而去执行其他任务;等 IO 完成收到通知,再回来继续执行剩下逻辑。

生活比喻:异步:点火烧水,不用站着等水开,趁等待的这段时间去洗菜;水开了,回来关火。

关键区分

  • 同步:排队执行,等待时卡住不动

  • 异步:遇到 IO 等待主动让出,切换执行别的任务

  • ⚠️ 异步不是多核并行计算,适合 IO 等待多的场景;不适合大量 CPU 密集计算

同步模拟阻塞示例(time.sleep 模拟 IO 等待)

 

import time

def task(name, delay):
    print(f"{name} 开始执行,需要等待{delay}秒")
    time.sleep(delay) # sleep模拟IO阻塞,程序原地卡住
    print(f"{name} 执行完毕")

start = time.time()
task("任务A", 2)
task("任务B", 2)
end = time.time()
print(f"总耗时:{end - start:.2f}秒")

 

运行结果:总耗时大约 4 秒,A 全部做完才做 B。

⚔️ Kata 实战任务

任务需求:

  1. 读懂同步代码,运行观察总耗时

  2. 理解 time.sleep 代表 IO 阻塞

  3. 观察:任务 A 等待的时候,任务 B 完全不会启动

参考代码

 

import time

def query_data(task_name, wait_sec):
    print(f"{task_name}:开始查询数据,需要等待 {wait_sec} s")
    # time.sleep 模拟IO阻塞(模拟网络/数据库查询等待)
    time.sleep(wait_sec)
    print(f"{task_name}:查询完成!")

start_time = time.time()
# 同步串行执行
query_data("查询1", 2)
query_data("查询2", 2)
end_time = time.time()

print(f"\n✅ 全部任务结束,总耗时:{end_time - start_time:.2f} 秒")

 

运行输出:

 

查询1:开始查询数据,需要等待 2 s
查询1:查询完成!
查询2:开始查询数据,需要等待 2 s
查询2:查询完成!

✅ 全部任务结束,总耗时:4.01 秒

 

🧠 思考题

  1. 上面同步代码,两个任务都等待 2 秒,总耗时接近 4 秒。如果用异步并发,理论最少耗时大概多少?

  2. IO 阻塞和 CPU 计算繁重,哪一类场景适合使用异步?