zoukankan      html  css  js  c++  java
  • Python-asyncio的使用

    async/await是python3.5用于定义协程的关键字,async定义一个协程, await用于挂起阻塞的异步调用接口 Asyncio是单线程的,只有一个主线程,但是可以进行多个不同的(task),这里的任务,就是特殊的future对象. 这些不同的任务,被一个叫做event loop的对象所控制。

    官方网站: https://docs.python.org/3/library/asyncio.html

    asyncio简单用法

    async def get_html(url):
        print("start get url")
        await asyncio.sleep(2)
        print("end get url")
    
    def test_1():
        start_time = time.time()
        loop = asyncio.get_event_loop()
        tasks = [get_html("http://www.baidu.com") for _ in range(10)]
        loop.run_until_complete(asyncio.wait(tasks)) # 接收一个可迭代对象
        loop.close()
        print(time.time() - start_time)

    接收返回值

    async def get_html1(url):
        print("start get url")
        await asyncio.sleep(2)
        print("end get url")
        return "返回值"
    def test_2():
        start_time = time.time()
        loop = asyncio.get_event_loop()
        # 多个请求
        tasks = [asyncio.ensure_future(get_html1("http://www.baidu.com")) for _ in range(10)]
        loop.run_until_complete(asyncio.wait(tasks))
        for task in tasks:
            print(task.result())
        print(time.time() - start_time)
        # 单个请求
        task = asyncio.ensure_future(get_html1("http://www.baidu.com"))
        loop.run_until_complete(task)
        loop.close()
        print(task.result())

    gather用法

    def test_3():
        loop = asyncio.get_event_loop()
        # gather更高级
        group1 = [get_html('http://www.baidu.com') for i in range(2)]
        group2 = [get_html('http://www.baidu.com+++++') for i in range(2)]
        loop.run_until_complete(asyncio.gather(*group1, *group2))
        group1 = [get_html('http://www.baidu.com') for i in range(2)]
        group2 = [get_html('http://www.baidu.com+++++') for i in range(2)]
        g1 = asyncio.gather(*group1)
        g2 = asyncio.gather(*group2)
        loop.run_until_complete(asyncio.gather(g1, g2))
        loop.close()

    回调函数

    from functools import partial
    
    def callback1(url, arg ,feture):
        print(url, arg)
        print(f"回调函数结果:{feture.result()}")
    
    def test_4():
        loop = asyncio.get_event_loop()
        task = asyncio.ensure_future(get_html1("http://www.baidu.com"))
        # 回调函数 会把 task 传入到 callback
        # 注意参数位置 task 最后一个传进去的
        task.add_done_callback(partial(callback1, "http://www.baidu.com", "gdwjd"))
        loop.run_until_complete(task)
        print("测试结果", task.result())

    取消协程

    def test_5():
        tasks = [get_html("http://www.baidu.com") for _ in range(3)]
        loop = asyncio.get_event_loop()
        try:
            loop.run_until_complete(asyncio.wait(tasks))
        except Exception as e:
            all_tasks = asyncio.Task.all_tasks()
            for task in all_tasks:
                print("=====", task.cancel())
            loop.stop()
            loop.run_forever()
        finally:
            loop.close()

    协程套协程

    import aiohttp
    async def get(url, i):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as res:
                return res.status, i
    
    async def hello(i):
        url = "http://www.taobao.com"
        print(i, url)
        res = await get(url, i)
        print("状态码:", res)
    
    def test_6():
        start = time.time()
        loop = asyncio.get_event_loop()
        tasks = [asyncio.ensure_future(hello(i)) for i in range(50)]
        loop.run_until_complete(asyncio.wait(tasks))
        loop.close()
        print(time.time() - start)

    示例:生产者与消费者通信

    async def consumer(queue, id):
        while True:
            val = await queue.get()
            print('{} get a val: {}'.format(id, val))
            await asyncio.sleep(1)
    
    async def producer(queue, id):
        for i in range(5):
            val = random.randint(0, 10)
            await queue.put(val)
            print('{} put a val: {}'.format(id, val))
            await asyncio.sleep(1)
    
    async def main():
        queue = asyncio.Queue()
        consumer_1 = asyncio.create_task(consumer(queue, 'consumer_1'))
        consumer_2 = asyncio.create_task(consumer(queue, 'consumer_2'))
        producer_1 = asyncio.create_task(producer(queue, 'producer_1'))
        producer_2 = asyncio.create_task(producer(queue, 'producer_2'))
        # 超过10秒,没有消息过来就会取消协程
        await asyncio.sleep(10)
        consumer_1.cancel()
        consumer_2.cancel()
        await asyncio.gather(consumer_1, consumer_2, producer_1, producer_2, return_exceptions=True)
    
    def test_7():
        start = time.perf_counter()
        asyncio.run(main())
        end = time.perf_counter()
        print(end - start)
  • 相关阅读:
    DeepZoomPix照片浏览的新体验
    SilverTouch系列 SilverAlbum Ver1.0
    手把手玩转win8开发系列课程(28)
    百度之星试题每周一练
    手把手玩转win8开发系列课程(27)
    WP7和Android控件对照表
    门户网站负载均衡技术的六大新挑战
    RA_CUST_TRX_LINE_GL_DIST_ALL
    XML PUBLISHER输出excel存在科学计数
    中文字符按拼音排序
  • 原文地址:https://www.cnblogs.com/zhouzetian/p/14242411.html
Copyright © 2011-2022 走看看