1、异步编程模式的好处
在编写程序的时候,往往会写出下面这样的程序:
int main( int argc , char *argv[])
{
...
int iRet1 = Func1();
int iRet2 = Func2();
int iRet3 = Func3();
...
}
在程序执行的时候,必须等到Func1()执行返回后,才能继续执行下面的语句,若Func1()是一个耗时间的操作,那么main线程将会不对其他的操作进行响应。其实很多的人的想法,就是另起一个线程执行该Func1函数。不让其阻塞主线程的执行。good!很好的想法,下面对其进行进一步的分析。
(1)同步模型
下面的图就是上面执行流程的描述:
这是最简单的编程方式。 在一个时刻, 只能有一个任务在执行, 并且前一个任务结束后一个任务才能开始。 如果任务都能按照事先规定好的顺序执行, 最后一个任务的完成意味着前面所有的任务都已无任何差错地完成并输出其可用的结果—这是多么简单的逻辑。
(2)多线程模型
下面的图就是多线程模型执行的描述(符合上面的讨论):
在这个模型中,每个任务都在单独的线程中完成。 这些线程都是由操作系统来管理, 若在多处理机、 多核处理机的系统中可能会相互独立的运行, 若在单处理机上, 则会交错运行。 关键点在于,在线程模式中,具体哪个任务执行由操作系统来处理。 但编程人员 则只需简单地认为: 它们的指令流是相互独立且可以并行执行。 虽然,从图示看起来很简单, 实际上多线程编程是很麻烦的,任务之间的要通信就要是线程之间的通信。 线程间的通信那不是一般的复杂。 什么邮槽、 通道、共享内存等.
(3)异步编程模型
下面的图就是异步编程模型执行的描述:
在这个模型中,任务是交错完成,值得注意的是: 这是在单线程的控制下。 这要比多线程模型简单多了,因为编程人员总可以认为只有一个任务在执行, 而其它的在停止状态。 虽然在单处理机系统中, 线程也是像图 3那样交替进行。 但作为程序员在使用多线程时, 仍然需要使用图 2而不是图 3的来思考问题,以防止程序在挪到多处理机的系统上无法正常运行(考虑到兼容性)。但单线程的异步程序不管是在单处理机还是在多处理机上都能很好的运行。在异步编程模型与多线程模型之间 还有一个不同: 在多线程程序中,对于停止某个线程启动另外一个线程, 其决定权并不在程序员 手里而在操作系统那里,因此,程序员在编写程序过程中必须要假设在任何时候一个线程都有可能被停止而启动另外一个线程。 相反, 在异步模型中, 一个任务要想运行必须显式放弃当前运行的任务的控制权。 这也是相比多线程模型来说,最简洁的地方。 值得注意的是: 将异步编程模型与同步模型混合在同一个系统中是可以的。 但在介绍中的绝大多数时候, 我们只研究在单个线程中的异步编程模型。
上面已经介绍了三种模型,总结起来就是:异步编程模式比多线程模型简单在于其单指令流与显示地放弃对任务的控制权而不是被操作系统随机地停止,但是异步模型要比同步模型复杂就在于,程序员必须将任务组织成序列来交替的小步完成,因此若其中一个任务用到另一个任务的输出,则依赖的任务(即接收输出的任务)需要被设计为要接收系列比特或者分片而不是一下全部接收。
2、异步编程模型应用的场景
与同步模型相比, 异步模型的优势在如下情况下会得到发挥:
- 有大量的任务, 以至于可以认为在一个时刻至少有一个任务要运行
- 任务执行大量的I/O操作, 这样同步模型就会在因为任务阻塞而浪费 大量的时间
- 任务之间 相互独立, 以至于任务内部的交互很少。
这些条件大多在CS模式中的网络比较繁忙的服务器端出现(如WEB服务器) 。 每个任务代表一个客户端进行接收请求并回复的I/O操作。 客户的请求(相当于读操作) 都是相互独立的。 因此一个网络服务是异步模型的典型代表。