Python协程
阅读 (216368)
分享
一、概念
-
子程序
在所有的语言中都是层级调用的,比如A中调用B,B在执行过程中调用C,C执行完返回,B执行完返回,最后是A执行完毕。这是通过栈实现的,一个函数就是一个执行的子程序,子程序的调用总是有一个入口、一次返回,调用的顺序是明确的
-
协程
又称微线程(纤程),是一种用户态的轻量级线程
-
理解协程
普通理解:线程是系统级别的,它们是由操作系统调度。协程是程序级别,由程序员根据需求自己调度。我们把一个线程中的一个个函数称为子程序,那么一个子程序在执行的过程中可以中断去执行别的子程序,这就是协程。也就是说同一个线程下的一段代码1执行执行着就中断,然后去执行另一段代码2,当再次回来执行代码1时,接着从之前的中断的位置继续向下执行
专业理解:协程拥有自己的寄存器上下文和栈,协程在调度切换时,将寄存器上下文和栈保存到其他的地方,在切换回来时,恢复先前保存的寄存器上下文和栈。因此,协程能后保留一次调用的状态,每次过程重入时,就相当于进入上一次调用的状态
-
优点
a、无需线程上下文切换的开销,协程避免了无意义的调度,从而提高了性能,但是程序员必须自己承担调度的任务,同时协程也失去了标准线程使用多CPU的能力
b、无需原子操作锁定及同步的开销
c、方便切换控制流,简化编程模型
d、高并发+高可扩展+低成本:一个CPU支持上万个协程不是问题
-
缺点
a、无法利用多核CPU,协程的本质是单个线程,它不能同时将多个CPU的多个核心使用上,协程需要和进程匹配使用才能运行在多个CPU上。但是一般不需要,除非是CPU计算密集型的应用
b、进行阻塞操作(操作IO)会阻塞整个程序
-
代码
def run1(): print(1) print(2) print(3) print(4) def run2(): print("a") print("b") print("c") print("d") run1() run2()
-
结果
正常结果
1 2 3 4 a b c d
协程实现的结果(假设)
1 a b 2 3 c 4 d
二、数据传递
-
数据传递
def func(): print("------------------1") r = yield 1 print("------------------2", r) yield 2 print("------------------3") yield 3 print("------------------4") yield 4 print("------------------5") yield 5 g = func() # print(next(g)) # print(next(g)) # print(next(g)) # print(next(g)) # print(next(g)) # 启动生成器g,从第二个开始send的参数值会放到yield处 print(g.send(None)) print(g.send(11))
-
生产者与消费者
import time def product(c): print("启动生产者……") #启动消费者 c.send(None) for data in ["good", "nice", "cool", "handsome"]: print("生产出%s数据"%(data)) #将数据交给消费者 c.send(data) time.sleep(2) #关闭消费者 c.close() print("结束生产者……") def customer(): print("启动消费者……") while True: print("等待生产者生产数据") #获取数据 value = yield print("消费了%s"%value) c = customer() product(c)
需要
登录
才可以提问哦
: