Python协程学习笔记

Python协程学习笔记

协程

◆ 协程就是协同多任务

◆ 协程在一个进程或者是一个线程中执行

◆ 不需要锁机制

◆ 对多核CPU的利用——多进程+协程

协程的实现

◆ python3.5以前

使用生成器(yield)来实现

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def count_down(n):
""" 倒计时效果 """
while n > 0:
yield n
n -= 1


def yield_test():
while True:
n = (yield)
print(n)


if __name__ == '__main__':
rest = yield_test()
next(rest)
rest.send('6666')

◆ python3.5以后

使用async和await关键字实现

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import asyncio


async def do_sth(x):
""" 定义协程函数 """
print('等待中:{0}'.format(x))
# 等待5秒,表现await作用
await asyncio.sleep(x)

# 判断是否为协程函数
print(asyncio.iscoroutinefunction(do_sth))

coroutine = do_sth(5)
# 事件的循环队列
loop = asyncio.get_event_loop()
# 注册任务
task = loop.create_task(coroutine)
print(task)
# 等待协程任务执行结束
loop.run_until_complete(task)
print(task)

asyncio模块

◆ get_event_loop()获得事件循环队列

◆ run_until_complete()注册任务到队列

◆ 在事件循环中调度其执行前,协程对象不执行任何操作

◆ asyncio模块用于事件循环

await 关键字

◆ 等待协程执行完成

◆ 当遇到阻塞调用的函数的时候,使用await方法将协程的控制权让出,以便loop调用其他的协程

协程之间的数据通信

◆ 嵌套调用

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import asyncio

async def compute(x, y):
print('计算 x + y => {0}+{1}'.format(x, y))
await asyncio.sleep(3)
return x + y

async def get_sum(x, y):
rest = await compute(x, y)
print('{0} + {1} = {2}'.format(x, y, rest))

# 拿到事件循环
loop =asyncio.get_event_loop()
loop.run_until_complete(get_sum(1, 2))
loop.close()

◆ 队列

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 1. 定义一个队列
# 2. 让两个协程进行通信
# 3. 让其中一个协程往队列中写入数据
# 4. 让另一个协程从队列中删除数据


import asyncio
import random


async def add(store, name):
"""
写入数据到队列
:param store: 队列的对象
:return:
"""
for i in range(5):
# 往队列中添加数字
num = '{0} - {1}'.format(name, i)
await asyncio.sleep(random.randint(1, 5))
await store.put(i)
print('{2} add one ... {0}, size:{1}'.format(
num, store.qsize(), name))


async def reduce(store):
"""
从队列中删除数据
:param store:
:return:
"""
for i in range(10):
rest = await store.get()
print(' reduce one.. {0}, size:{1}'.format(rest, store.qsize()))


if __name__ == '__main__':
# 准备一个对列
store = asyncio.Queue(maxsize=5)
a1 = add(store, 'a1')
a2 = add(store, 'a2')
r1 = reduce(store)

# 添加到事件队列
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(a1, a2, r1))
loop.close()
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×