异步和同步
什么是异步?
异步就是一项任务不一次性执行完,先执行第一段转而执行其他任务,等做好了准备,再回来执行剩下第二段。
不连续的执行就叫做异步,相应的,连续的执行就叫做同步。
应用场景:
在一个任务中包含打开文件或建立远程连接等耗时操作,若采用同步执行,则在读取文件或建立连接的过程中,程序只能干等着,什么事也做不了。
如果使用异步执行,遇到耗时的阻塞则挂起,程序控制权交给别的任务,等别的任务执行完了或者也挂起,这时阻塞操作也已经执行完了,这时接着执行下面的操作即可。
协程coroutine
协程是由 async
关键字定义的对象,它的直接调用不会立即执行函数,而是返回一个写成对象,此对象只有注册到事件循环中,由事件循环调用。
await
await
是python3.5定义的,用以取代之前的 yield from
。async
定义一个协程, await
用于挂起阻塞的异步接口。
看下面的例子:
import asyncio, time
start = time.time()
now = lambda :time.time()
async def do_something(s):
print('waiting: %s s' % s)
await asyncio.sleep(s)
print('mission done {}'.format(s))
loop = asyncio.get_event_loop()
tasks = [do_something(2), do_something(1), do_something(4)]
loop.run_until_complete(asyncio.wait(tasks))
print(now()-start)
loop.close()
运行结果:
waiting: 1 s
waiting: 2 s
waiting: 4 s
mission done 1
mission done 2
mission done 4
3.9893088340759277
本来如果同步执行,程序至少需要7秒,但由于使用了协程,在遇到阻塞时程序挂起并未等待在阻塞处,转而执行其他的协程对象,从而减少程序运行时间。
而且,如果我们打印当前线程名或发现,三个协程一直是在一个线程下执行的,也就是一个线程实现了并发操作。
下面用一个形象的例子描述多协程并发执行的过程:
晚自习,一个老师辅导多名学生,给A同学讲解完一道题的做法后,让其自己理解,做完这道题。
做这道题是个耗时的操作,这时老师不必一直等他做完,可以去辅导B学生。
给B讲解一道题,再让其理解做完,这时A的那道题已经做完了,可以回到A身边,讲解下一道题了。
老师在A和B之间交替讲解,直到二者均完成其作业为止。
其中,老师就是一线程,学生 A 和 B 是两个协程。学生做完所有作业是missionA 和 mission B。
老师对每道题的讲解是正常的程序执行。
听完老师讲解后,学生写每道题的过程是耗时的阻塞操作。
网友评论