协程
◆ 协程就是协同多任务
◆ 协程在一个进程或者是一个线程中执行
◆ 不需要锁机制
◆ 对多核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)) 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
|
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()
|