python中的协程

引子1

# -*-coding:utf-8-*-
# Author:Lai
import aiohttp, aiofiles, asyncio


# 下载器
async def fetch(session, url):
    async with session.get(url) as resp:
        return await resp.read()


# 单个任务
async def main1():
    async with aiohttp.ClientSession() as session:
        url = "https://www.xxx.com"
        res = await fetch(session, url)
        print(res.decode("GBK"))


# 多个任务
async def main2():
    async with aiohttp.ClientSession() as session:
        urls = ["https://www.xxx1.com","https://www.xxx2.com"]
        # 1.注意asyncio.create_task会立刻加入事件循环,若写到coro外,事件循环因为没有创建会报错,错误如引子2
        # 2.在coro内是否加上asyncio.create_task 好像影响不大,后续继续观察
        tasks = [asyncio.create_task(fetch(session, url)) for url in urls]
        b_list = await asyncio.gather(*tasks)



if __name__ == "__main__":
    asyncio.run(main1())
    # asyncio.run(main1()) 相当于 loop = asyncio.get_event_loop() 和 loop.run_until_complete(main1())这两句

引子2

# -*-coding:utf-8-*-
# Author:Lai
import asyncio


async def test1():
    print(3)
    await asyncio.sleep(1)


async def main():
    print(1)
    await asyncio.sleep(2)
    print(2)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    ####################################此处错误,事件循环因为没有创建会报错
    tasks = [
        asyncio.create_task(main()),
        asyncio.create_task(test1())
    ]
    ####################################
    
    tasks = [
        main(),
        test1()
    ]
    loop.run_until_complete(asyncio.gather(*tasks))

引子3 同步模块与asyncio系异步混用

# -*-coding:utf-8-*-
# Author:Lai
import asyncio, requests, aiofiles
import uuid
from os import path


async def downloaderPic(url):
    loop = asyncio.get_event_loop()
    # 第一个参数是None,说明是线程
    future = loop.run_in_executor(None, requests.get, url)
    resp = await future
    return resp


async def main():
    urls = [
        "https://img.tupianzj.com/uploads/allimg/202003/9999/rnaf199ff691.jpg",
        "https://img.tupianzj.com/uploads/190301/9-1Z30116242C19.jpg",
        "https://img.tupianzj.com/uploads/allimg/180505/9-1P505113Q90-L.jpg"
    ]
    tasks = [downloaderPic(url) for url in urls]
    res = await asyncio.gather(*tasks)
    print(res)


if __name__ == "__main__":
    asyncio.run(main())

引子4 aiomysql的使用

# -*-coding:utf-8-*-
# Author:Lai

import asyncio
import aiomysql
import random

def create_name():
    res_name = ""
    m = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    for _ in range(5):
        index = random.randint(0,25)
        res_name += m[index]
    return res_name


def create_age():
    return random.randint(20,60)


async def mysqlHelper():
    pool = await aiomysql.create_pool(host='127.0.0.1', port=3306,
                                      user='root', password='localhost',
                                      db='test2', charset='utf8')
    async with pool.acquire() as conn:
        async with conn.cursor() as cur:
            for _ in range(100000):
                name = create_name()
                age = create_age()
                await cur.execute("INSERT INTO info333(name,age) VALUES(%s,%s)",(name,age))
        await conn.commit()


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(mysqlHelper())

生产者与消费者模型

import asyncio

async def producer(q:asyncio.Queue):
    n = 0
    while True:
        await asyncio.sleep(0.5)
        print(f"生产了{n}号")
        await q.put(n)
        n += 1


async def customer(q:asyncio.Queue):
    while True:
        await asyncio.sleep(1)
        res = await q.get()
        print(f"消耗了{res}号")


async def main():
    q = asyncio.Queue()
    tasks = [producer(q), customer(q)]
    await asyncio.gather(*tasks)



if __name__ == "__main__":
    asyncio.run(main())
posted @ 2020-08-29 21:03  lilied  阅读(108)  评论(0编辑  收藏  举报