前述的定义协程及并发编程似乎与多线程编程相比更加复杂: 需要定义协程函数,使用async 、 await等关键字 , 还要掌握await后面必须是哪些对象等。这些复杂的操作都是具体的高效应用做铺垫,接下来我们看一下协程在I/O密集型任务中具有怎样的优势。
我们以常用的网络请求场景为例 ,网络请求较多的应用就是I/O密集型任务。首先需要简历一个服务器来响应Web请求,为方便演示,我们使用轻量级的Web框架Flask来建立一个服务器。
【示例 1】启动一个简单的Web服务器(coroutine_flask_demo)
在上述代码中, 我们定义一个Flask服务,主入口是index()方法, 方法中先调用了sleep()方法休眠3秒, 然后返回结果。 也就是说,每次请求这个接口至少要消耗3秒,这样我们就模拟一个慢速的服务接口。注意,服务启动时,run()方法添加了一个参数threaded , 表明Flask启动了多线程模式 , 否则默认是只有一个现线程的。 如果不启动多线程模式,那么同一时刻遇到多个请求时,只能顺次处理,这样即使我们使用协程异步请求了这个服务,也只能一个个排队等待,瓶颈就会出现在服务端。所以,多线程模式是有必要打开的。
运行结果如下: