一、引子 (超哥协程)
并发本质:保存状态+切换
cpu正在运行一个任务,转而执行另一个任务的情概况:1、是该任务发生了阻塞;2、该任务计算的时间过长或有一个优先级更高的程序替代了它。
协程本质上就是一个线程,使用代码来控制任务的切换。以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。
ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态
一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。
二、yield 模拟单线程之间的任务切换过程
#1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 #2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换
import time def jishi1hao(): for i in range(6): print("快快来~~~~") yield #yield 可以记录任务的执行状态 time.sleep(1) print("%s号客户2s搞定"%i) def jishi2hao(): g=jishi1hao() #获取到生成器 g.__next__() #执行第一段函数,到第一个yield结束 for i in range(5): time.sleep(1) print("%s号技师正在忙!!!"%i) g.__next__() #继续到下一个yield jishi2hao() #使用yield可以实现程序的切换执行,但是不能提高效率,只是简单的程序分段穿插运行