asyncio 协程库(常见场景!)

python 的协程:
1,Python对协程的支持是通过generator实现的
2,协程是由程序自身控制的程序间的切换
asyncio 协程库:
1,通过async关键字定义一个协程(coroutine),协程也是一种对象。协程不能直接运行,需要把协程加入到事件循环(loop)
2,所谓task对象是Future类的子类。保存了协程运行后的状态,用于未来获取协程的结果。
3,future: 代表将来执行或没有执行的任务的结果。它和task上没有本质的区别
4,async/await async定义一个协程,await用于挂起阻塞的异步调用接口
5,aiohttp 异步web 请求库
6,aiomysql 异步数据库连接库
常用方法:
import asyncio
import time
import aiohttp

now = lambda: time.time()

async def do_some_work(x):
    print('Waiting: ', x)
    async with aiohttp.ClientSession() as session:
        async with session.get('http://www.baidu.com') as resp:
            print(resp.status)
    return 'Done after {}s'.format(x)

async def main():
    coroutine1 = do_some_work(1)
    coroutine2 = do_some_work(2)
    coroutine3 = do_some_work(4)

    tasks = [
        # 创建 task 的另一种方式!
        asyncio.ensure_future(coroutine1),
        asyncio.ensure_future(coroutine2),
        asyncio.ensure_future(coroutine3)
    ]
    # await 表明 如果遇到阻塞就切换其他的 task
    # as_completed 返回一个迭代对象
    for task in asyncio.as_completed(tasks):
        result = await task
        print('Task ret: {}'.format(result))

def callback(t, future):
    print(t)
start = now()

# 开启一个无限的循环,程序员会把一些函数注册到事件循环上。
# 当满足事件发生的时候(本次是遇到阻塞),调用相应的协程函数
loop = asyncio.get_event_loop()

#将协程变成 task
task = loop.create_task(main())
# 获取 task 状态
print(task.result)
import functools
# 偏函数注册回调参数!
task.add_done_callback(functools.partial(callback, 2))
# task 注册到 循环之中
loop.run_until_complete(task)

# 将协程函数注册到循环之中(一步到达),等于前两步骤
# loop.run_until_complete(main())
print('TIME: ', now() - start) # 是同步的 1/3 时间消耗
异步操作mysql连接: asyncio + sqlalchemy
1, 创建一个全局的连接池,每个HTTP请求都可以从连接池中直接获取数据库连接。
2, 使用连接池的好处是不必频繁地打开和关闭数据库连接
import aiomysql
import asyncio

async def select(loop, sql, pool):
    async with pool.acquire() as conn:
     async with conn.cursor() as cur:
      await cur.execute(sql)
      r = await cur.fetchone()
      print(r)

async def insert(loop, sql, pool):
    async with pool.acquire() as conn:
     async with conn.cursor() as cur:
      await cur.execute(sql)
      await conn.commit()

async def main(loop):
    pool = await aiomysql.create_pool(
     host='127.0.0.1',
     port=3306,
     user='root',
     password='123456',
     db='test',
     loop=loop)
    c1 = select(loop=loop, sql='select * from minifw limit 1', pool=pool)
    c2 = insert(loop=loop, sql="insert into minifw (name) values ('hello')", pool=pool)

    tasks = [asyncio.ensure_future(c1), asyncio.ensure_future(c2)]
    return await asyncio.gather(*tasks)


if __name__ == '__main__':
    cur_loop = asyncio.get_event_loop()
    cur_loop.run_until_complete(main(cur_loop))

 

posted @ 2019-01-06 19:51  十七楼的羊  阅读(1215)  评论(0编辑  收藏  举报