Python-:协程-生成器实现
协程
- 一句话解释就是: 单线程执行多任务
- 协程是线程的更小切分, 又称作'微线程':线程是系同级别的,是有操作系统调度, 而协程是程序级别的,使我们自己设置的规则调度
- 协程的概念: 在一个线程中会有很多的函数, 姑且就称为子程序吧, 在子程序执行的过程中,我们可以按照逻辑子程序执行正在执行的函数,让其执行其他的子程序,执行一段时间后,继续执行原来的子程序,且还是从原来中断的地方继续执行,类似 yield 的操作总之就是来回切换
- 协程无法利用多核资源(单进程单线程)
- 协程占用的资源小,切换效率高,一个CPU同时支持上万的协程都无压力
和线程的区别
相同点
- 协程在工作是和CPU在并发执行多个进程差不多,是通过轮转在进程之间来回切换,操作系统实现这种交错执行的机制是
上下文切换
: 栈(切换之前保存变量函数的调用),寄存器状态(用于执行流恢复后要做什么)
- 任何时刻 一个核心只能同时执行一个进程,当转移到新进程时,就要进行上下文切换(保存当前进程上下文,恢复新进程上下文,然后将控制权交给新进程),新进程就会从上次停止的地方开始
不同点
- 进程是内核调度,协程是用户态保存恢复的
- 进程会被强占(执行时被CPU强行切出),协程不存在如果协程不主动停止让出CPU则其他协程就没有执行的机会
- 多协程的程序其实就是单进程,单线程
- 协程只需要4k的栈就足够,进程占用的内存要大得多
Demo
import time
# 如果一个函数中定义包含 yield 的关键字, 那么这个函数不再是一个普通的函数, 而是一个生成器
def consumer(name): # 生成器
print('{}, 要开始吃包子了'.format(name))
while True:
baozi = yield # 暂停, 记录位置, 返回跳出(接收下面send发送的数据,接收到数据后才会继续执行)
print('包子{}, {}吃了'.format(baozi, name))
def producer(name)
c = consumer('消费者') # 只是变成了一个生成器
c.__next__() # next只是唤醒yield 不传递值
for i in range(4):
time.sleep(1)
print('{}, 做了包子{}'.format(name, i))
c.send(i)
if __name__ == '__main__'
producer('消费者')