标签:pytho 中心 合作 and for users 学习 实现 关键字
流畅的Python书中的协程部分版本太低,而且讲的比较少,这次根据Python3标准库书中实例来学习记录asyncio的使用。
asyncio模块提供了使用次饿成构建并发应用的工具。threading模块通过应用线程并发,mutilprocessing使用系统进程实现并发,asyncio则使用一个单线程单进程的方法来实现并发,应用的各个部分会彼此合作,在最优的时刻显式地切换任务。
asyncio提供的框架以一个事件循环(event loop)为中心,这是一个首类对象,负责高效地处理I/O事件、系统事件、和应用的上下文切换。
就现在本人的了解,一般的io应用中,还是以多线程使用为主,自己在写协程并发的时候,多个协程之间,无法有效的设置条件交出控制权。
唯一能应用的包,就一个aiohttp,如果我想用另外的包实现协程,基本无法做到,然而协程asyncio包就像流畅的Python书中所说,大部分在讲概念和API,
也只能希望后面能有更加丰富的包来配合协程,或者等我哪一天成为高手,写出能配合协程的包。
2、利用协程合作完成多任务
import asyncio
async def coroutine():
print(‘in coroutine‘)
# 定义事件循环
event_loop = asyncio.get_event_loop()
try:
print(‘starting coroutine‘)
coro = coroutine()
print(‘entering event loop‘)
# 运行协程
event_loop.run_until_complete(coro)
finally:
print(‘closing event loop‘)
event_loop.close()
/usr/local/bin/python3.7 /Users/shijianzhong/study/t_asyncio/asyncio_coroutine.py starting coroutine entering event loop in coroutine closing event loop Process finished with exit code 0
先通过get_event_loop创建一个默认的事件循环,run_until_complete方法驱动里面的协程,最后关闭事件循环。
从协程返回值
import asyncio
# 有返回值
async def coroutine():
print(‘in coroutine‘)
return ‘result‘
# 定义事件循环
event_loop = asyncio.get_event_loop()
try:
print(‘starting coroutine‘)
coro = coroutine()
print(‘entering event loop‘)
# 运行协程,获取值
return_value = event_loop.run_until_complete(coro)
print(f‘it returned: {return_value!r}‘)
finally:
print(‘closing event loop‘)
event_loop.close()
/usr/local/bin/python3.7 /Users/shijianzhong/study/t_asyncio/asyncio_coroutine_return.py starting coroutine entering event loop in coroutine it returned: ‘result‘ closing event loop Process finished with exit code 0
串链协程
import asyncio
async def outer():
print(‘in outer‘)
print(‘waiting for result1‘)
# 接收phase1()协程产生的值
result1 = await phase1()
print(‘waiting for result2‘)
# 接收phase2()协程产生的值
result2 = await phase2(result1)
return result1, result2
async def phase1():
print(‘in parse1‘)
return ‘result1‘
async def phase2(arg):
print(‘in phase2‘)
return ‘result2 derived from {}‘.format(arg)
event_loop = asyncio.get_event_loop()
try:
return_value = event_loop.run_until_complete(outer())
print(f‘return_value:{return_value!r}‘)
finally:
event_loop.close()
/usr/local/bin/python3.7 /Users/shijianzhong/study/t_asyncio/asyncio_coroutine_chain.py in outer waiting for result1 in parse1 waiting for result2 in phase2 return_value:(‘result1‘, ‘result2 derived from result1‘) Process finished with exit code 0
生成器而不是协程
Python3.5开始
async 代替了@asyncio.coroutine
await 代替了 yield from
本人觉得await 还是yield from更加直观。
3、调度常规函数调用
这个使用的话,需要把事件循环传递放入协程中,协程中通过事件循环的方法去激活需要调用的函数。
在传入事件循环的协程里面必须设置asyncio.seleep,要不然协程不会让出控制权,事件循环根本无法激活调用函数。
import asyncio
from functools import partial
def callback(arg, *, kwarg=‘default‘):
print(f‘callback invoked with {arg} and {kwarg}‘)
async def main(loop):
print(‘registering callbacks‘)
# 调用函数,只能传入一个参数,多参数传入调用partial
loop.call_soon(callback, 1)
# 通过partial传入关键字参数
wrapped = partial(callback, kwarg=‘not default‘)
loop.call_soon(wrapped, 2)
await asyncio.sleep(.1)
event_loop = asyncio.get_event_loop()
try:
print(‘entering event loop‘)
event_loop.run_until_complete(main(event_loop))
finally:
event_loop.close()
/usr/local/bin/python3.7 /Users/shijianzhong/study/t_asyncio/asyncio_call_soon.py entering event loop registering callbacks callback invoked with 1 and default callback invoked with 2 and not default Process finished with exit code 0
用Delay调度回调
call_soon是直接调用,call_later()第一个参数可以传入延后的事件,单位为秒,第二个参数为function
在传入事件循环的协程里面必须设置asyncio.seleep,且大于最迟的调用函数时间,要不然协程不会让出控制权,事件循环根本无法激活调用函数。
import asyncio
from functools import partial
def callback(arg):
print(f‘callback invoked {arg}‘)
async def main(loop):
print(‘registering callbacks‘)
# 调用函数,第一个参数传入时间
loop.call_later(0.2, callback, 1)
loop.call_later(0.1, callback, 2)
# 这个很重要
await asyncio.sleep(.21)
event_loop = asyncio.get_event_loop()
try:
print(‘entering event loop‘)
event_loop.run_until_complete(main(event_loop))
finally:
print(‘closing event loop‘)
event_loop.close()
/usr/local/bin/python3.7 /Users/shijianzhong/study/t_asyncio/asyncio_call_later.py entering event loop registering callbacks callback invoked 2 callback invoked 1 closing event loop Process finished with exit code 0
在指定事件内调度一个回调
实现这个目的的循环依赖的是一个所谓的单调时钟,用loop.time()生成,激活用call_at
import asyncio
import time
def callback(n, loop):
print(f‘callback {n} invoked at {loop.time()}‘)
async def main(loop):
# 运行结果来看,这now是从0开始的
now = loop.time()
print(f‘clock time: {time.time()}‘)
print(f‘loop time {now}‘)
print(‘registering callbacks‘)
# 加0.2秒
loop.call_at(now + .2, callback, 1, loop)
# 加0.1 秒
loop.call_at(now + .1, callback, 2, loop)
# 马上开始
loop.call_soon(callback, 3, loop)
await asyncio.sleep(1)
event_loop = asyncio.get_event_loop()
try:
print(‘entering event loop‘)
event_loop.run_until_complete(main(event_loop))
finally:
print(‘closing event loop‘)
event_loop.close()
/usr/local/bin/python3.7 /Users/shijianzhong/study/t_asyncio/asynvio_call_at.py entering event loop clock time: 1579366496.336677 loop time 0.086557153 registering callbacks callback 3 invoked at 0.086701756 callback 2 invoked at 0.189241196 callback 1 invoked at 0.29037571 closing event loop Process finished with exit code 0
asyncio:异步I/O、事件循环和并发工具(持续跟新中)
标签:pytho 中心 合作 and for users 学习 实现 关键字
原文地址:https://www.cnblogs.com/sidianok/p/12210857.html