Python-协程

前言:

子程序/函数:在所有语言中都是层级调用,比如:A调用B,在B执行的过程中又可以调用C,C执行完毕,B执行完毕返回,最后是A执行完毕。它是通过栈实现的,一个线程就是执行一个子程序,子程序调用总是一个入口,一次返回,调用的顺序是明确的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def C():
print('C---start')
print('C---end')


def B():
print('B---start')
C()
print('B---end')


def A():
print('A---start')
B()
print('A---end')


A()


概述

它看上去也是子程序,但执行过程中,在子程序的内部可中断,然后转而去执行别的子程序,不是函数调用。

协程的特点在于是一个线程来执行。

与线程相比,协程的执行效率极高,因为只有一个线程,也不存在同时写变量的冲突,在协程中共享资源不加锁,只需要判断状态。

协程原理

Python对协程的支持是通过generator实现的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def run():
print(1)
yield 10
print(2)
yield 20
print(3)
yield 30


# 协程的最简单风格,控制函数的阶段执行,节约线程或者进程的切换
# 返回值是一个生成器
m = run()
print(next(m))
print(next(m))
print(next(m))

数据传输

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def run():
# 空变量,存储的作用,data始终为空
data = ''
r = yield data
# r = a
print(1, r, data)
r = yield data
# r = b
print(2, r, data)
r = yield data
# r = c
print(3, r, data)
r = yield data


m = run()
# 启动m
print(m.send(None))
print(m.send('a'))
print(m.send('b'))
print(m.send('c'))
print('******')

生产者与消费者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def product(c):
c.send(None)
for i in range(5):
print(f'生产者产生数据{i}')
r = c.send(str(i))
print(f'消费者消费了数据{r}')
c.close()


def customer():
data = ''
while True:
n = yield data
if not n:
return
print(f'消费者消费了{n}')
data = '200'


c = customer()
product(c)