同步编程与异步编程

内存数据读写、磁盘寻道读写、网卡读写等操作都是 I/O 操作,同步程序的瓶颈在于漫长的 I/O 等待,想要提高程度效率必须减少 I/O 等待时间。

同步编程的改进方式有多进程、多线程,但对于 C10K 问题(Client 10000 Problem,即“在同时连接到服务器的客户端数量超过 10000 个的环境中,即便硬件性能足够,仍然无法正常提供服务”这样一个问题)都不是良好的解决方案

多进程的方式存在操作系统可调度进程数量上限较低,进程间上下文切换时间过长,进程间通信较为复杂等问题

而 Python 的多线程方式,由于存在众所周知的 GIL 锁,性能提升并不稳定,仅能满足成百上千规模的 I/O 密集型任务,多线程还有一个缺点是由操作系统进行抢占式调度存在竞态条件,可能需要引入锁与队列等保障原子性操作的工具

回调模式编码比较复杂

还有一种被称为异步的模式,它与事件编程(event programming)一样,对我们来说至关重要。在单处理器系统和多处理器系统中,异步活动的执行模型均可使用一个主控制流来实现

在并发执行的异步模式中,不同的任务在时间线上是相互交错的,而且一切都是在单一控制流(单线程)下进行的。一个任务的执行可以暂停,然后继续,不过这也改变了其他任务的执行时间

当执行某个任务时,其他任务没在执行

多线程编程模式与单线程异步并发模式的一个关键区别在于,前者由操作系统决定任务执行的时间线,即是否暂停某个线程的活动并开启另一个线程,而后者要求程序员假设某个线程可能被暂停,并随时被另一个线程取代

程序员可以将任务编写为一系列可以间断执行的小步骤;因此,如果某个任务需要使用另一个任务的输出,那么在编写该任务时就在程序中设定必须接受后者的输入

C10M 问题:如何利用 8 核心 CPU,64G 内存,在 10gbps 的网络上保持 1000 万并发连接