不止Rust,为什么很多语言都支持异步
本文首发公众号 猩猩程序员 欢迎关注
1.并发的基础——进程与线程
1. 进程 (Process)
- 是什么:进程是操作系统进行资源分配和调度的基本单位。简单来说,你电脑上运行的每一个程序(比如微信、Chrome浏览器)都是一个独立的进程。
- 核心特征:
- 比喻:一座座独立的工厂。每座工厂有自己的设备、原材料和工人,工厂之间互不干扰。如果想让两个工厂协作,需要通过复杂的物流系统(IPC)来运输物资。
2. 线程 (Thread)
- 是什么:线程是进程内的一个执行单元,是CPU调度的基本单位。一个进程可以包含多个线程。
- 核心特征:
- 比喻:工厂里的工人们。所有工人共享工厂的设备和原材料。多一个工人(线程),就能多一条生产线,提高生产效率。但工人们需要协调(加锁),否则会抢夺同一个设备导致混乱。
2.传统模型的瓶颈 - “等待”的代价
我们有了进程和线程,似乎可以通过“多开工人”的方式无限提升效率。但一个核心问题出现了:等待,或者说 阻塞I/O (Blocking I/O)。
- 什么是阻塞I/O? I/O(Input/Output)指的是输入/输出操作,通常指那些速度远慢于CPU的操作,比如:当一个线程执行到这些操作时,它必须停下来,“阻塞” 在原地,直到操作完成。此时,CPU是被这个线程霸占着,但它什么也没干,只是在空等。这造成了巨大的资源浪费。
- 生动的例子:咖啡店的故事无论是单线程还是多线程,只要是同步阻塞模型,“等待” 这个问题就无法根本解决。线程(工人)的大部分时间可能都浪费在等待慢速I/O(设备)上。
3.优雅的解决方案 - 异步编程
异步就是为了解决“等待”的浪费而生的。它的核心思想是:发起一个耗时操作后,不原地等待结果,而是立即返回去做别的事情。当操作完成后,系统会通知我,我再回来处理结果。
- 异步模型下的咖啡店(一个聪明的咖啡师)
- 异步编程的核心组件:事件循环 (Event Loop) 这个聪明的咖啡师,他的大脑里就在运行一个“事件循环”。
- 代码示例对比 (Rust)
4.异步的终极目的
异步的终极目的,是为了最大限度地压榨CPU的性能,提升系统在单位时间内的吞吐量 (Throughput)。
它通过以下方式实现这一目标:
- 剥离等待:将CPU从无效的I/O等待中解放出来,让它去做其他有意义的计算任务。
- 提高资源利用率:用极少的线程(甚至单线程)来处理海量的并发连接。对于每一个连接,只在真正需要CPU计算时才为其服务,其余时间(网络延迟、数据传输)CPU都在服务其他连接。
- 用并发实现高吞吐:在I/O密集型场景下(如Web服务器、数据库代理),异步可以用一个线程实现远超传统多线程模型的并发处理能力。
一句话总结:异步,就是一种用“协作式调度”的思想,让单线程或少数几个线程,通过不停地在不同任务之间切换,来模拟出大规模并发效果的编程模型,其核心是避免CPU在I/O上浪费时间。
总结对比
核心思想 | 多雇工人,一人一件事 | 一人多事,任务间切换 |
调度方式 | 抢占式(操作系统决定) | 协作式(代码自己决定何时让出CPU) |
开销 | 线程创建/切换开销大 | 开销极小(函数调用) |
适用场景 | CPU密集型 (多核并行计算) | I/O密集型 (高并发网络服务) |
编程复杂度 | 复杂(锁、死锁、数据竞争) | 较复杂(回调地狱、心智模型转换) |
本文首发公众号 猩猩程序员 欢迎关注
#Rust#