精华内容
下载资源
问答
  • 同步有序,异步无序 技巧: 几乎所有的异步框架都将异步编程模型简化:一次只允许处理一个事件。故而有关异步的讨论几乎都集中在了单线程内...一份详细的asyncio入门教程 [进阶]-Python3 异步编程详解(史上最全篇) F...
    同步有序,异步无序

    技巧:
    几乎所有的异步框架都将异步编程模型简化:一次只允许处理一个事件。故而有关异步的讨论几乎都集中在了单线程内。

    • 如果某事件处理程序需要长时间执行,所有其他部分都会被阻塞。
      所以,一旦采取异步编程,每个异步调用必须“足够小”,不能耗时太久。如何拆分异步任务成了难题。

    0.协程理解:
    一份详细的asyncio入门教程
    [进阶]-Python3 异步编程详解(史上最全篇)

    Future
    future是一个数据结构,表示还未完成的工作结果。事件循环可以监视Future对象是否完成。从而允许应用的一部分等待另一部分完成一些工作。Future
    获取Futrue里的结果
    future表示还没有完成的工作结果。事件循环可以通过监视一个future对象的状态来指示它已经完成。future对象有几个状态:

    • Pending
    • Running
    • Done
    • Cancelled
      创建future的时候,task为pending,事件循环调用执行的时候当然就是running,调用完毕自然就是done,如果需要停止事件循环,就需要先把task取消,状态为cancel。

    Task
    task是Future的一个子类,它知道如何包装和管理一个协程的执行。任务所需的资源
    可用时,事件循环会调度任务允许,并生成一个结果,从而可以由其他协程消费。

    • event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。

    • coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。

    • task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含任务的各种状态。

    • async/await 关键字:python3.5 用于定义协程的关键字,async定义一个协程,await用于挂起阻塞的异步调用接口。

    • 启动一个协程:

    import asyncio
    async def foo():
        print("这是一个协程")
    if __name__ == '__main__':
        loop = asyncio.get_event_loop()
        try:
            print("开始运行协程")
            coro = foo()
            print("进入事件循环")
            loop.run_until_complete(coro)
        finally:
            print("关闭事件循环")
            loop.close()
    

    原文链接:https://blog.csdn.net/ronon77/article/details/84854402
    ————————————————

    • asyncio.gather 和asyncio.wait区别:

    • 在内部wait()使用一个set保存它创建的Task实例。因为set是无序的所以这也就是我们的任务不是顺序执行的原因。wait的返回值是一个元组,包括两个集合,分别表示已完成和未完成的任务。wait第二个参数为一个超时值
      达到这个超时时间后,未完成的任务状态变为pending,当程序退出时还有任务没有完成此时就会看到如下的错误提示。
      gather的使用

    • gather的作用和wait类似不同的是。
      1.gather任务无法取消
      2.返回值是一个结果列表
      3.可以按照传入参数的 顺序,顺序输出
      ———————————————

    1.Aiohttp的ClientSession理解:

    • 你使用async
      以及await关键字将函数异步化。在hello()中实际上有两个异步操作:
      首先异步获取相应,然后异步读取响应的内容。

    • Aiohttp推荐使用ClientSession作为主要的接口发起请求。
      ClientSession允许在多个请求之间保存cookie以及相关对象信息。
      Session(会话)在使用完毕之后需要关闭,关闭Session是另一个异步操作,

    • 所以每次你都需要使用[async with]关键字。一旦你建立了客户端session,你可以用它发起请求。这里是又一个异步操作的开始。

    • 上下文管理器的with语句可以保证在处理session的时候,总是能正确的关闭它。
      要让你的程序正常的跑起来,你需要将他们加入事件循环中。
      所以你需要创建一个asyncio loop的实例, 然后将任务加入其中

    1. 例子:
    import asyncio
    from asyncio import sleep
    
    import aiohttp
    
    async def get_page():
        async with aiohttp.ClientSession() as session:
            # async with session.get('https://www.baidu.com') as resp:
            async with session.get('https://blog.csdn.net/u014595019/article/details/52295642') as resp:
                print(resp.status)
                print(await resp.text())
                await session.close()
    
    loop = asyncio.get_event_loop()
    # 执行多个函数任务队列
    tasks = [get_page(),sleep(5), get_page()]
    
    # asyncio.wait 并发协程
    loop.run_until_complete(asyncio.wait(tasks))
    
    # asyncio.gather 并发协程
    # loop.run_until_complete(asyncio.gather(tasks))
    
    
    # 执行单个函数
    # loop.run_until_complete(get_page())
    loop.close()
    

    在用asyncio.wait 执行时, tasks任务队列里的sleep(5),不会报错,会异步执行等待5秒,程序就自然结束运行,
    在asyncio.gather 执行sleep(5),报错:

    展开全文
  • asyncio.gather 和asyncio.wait区别: wait的使用 在内部wait()使用一个set保存它创建的Task实例。因为set是无序的所以这也就是我们的任务不是顺序执行的原因。wait的返回值是一个元组,包括两个集合,分别表示已完成...

    asyncio.gather 和asyncio.wait区别:

    wait的使用

    在内部wait()使用一个set保存它创建的Task实例。因为set是无序的所以这也就是我们的任务不是顺序执行的原因。wait的返回值是一个元组,包括两个集合,分别表示已完成和未完成的任务。wait第二个参数为一个超时值
    达到这个超时时间后,未完成的任务状态变为pending,当程序退出时还有任务没有完成此时就会看到如下的错误提示。

    gather的使用

    gather的作用和wait类似不同的是。
    1.gather任务无法取消。
    2.返回值是一个结果列表
    3.可以按照传入参数的 顺序,顺序输出。
    ———————————————

    展开全文
  • Python中的异步 # demo.py ...# asyncio.wait() 等待执行完成 async def foo(): await asyncio.sleep(2) return 50 async def main(): task = asyncio.create_task(foo()) # 执行其他任务 ...

    Python中的异步

    # demo.py
    import asyncio
    import time
    
    # Python 协程属于可等待对象,因此可以在其他协程中被等待 Python异步非阻塞雏形
    async def nested():
        # time.sleep(2)
        await asyncio.sleep(2)
        print('我是异步内的任务,我已经完成了')
        return 45
    
    async def main():
        print(time.strftime('%X'))
        start_time = time.time()
        task = asyncio.create_task(nested())  # 使用task去执行协程,就可以达到异步的效果,我们任务在这里是已经开启了协程,只是结果在其他位置等待。因此这个代码预期就是异步的。
        # await nested() # 这种调用会等待协程完成之后在继续向下执行,也就是协程会阻塞在这里,常用于同步协程
        # await task # 它会等待任务完成返回后 往下执行,如果在Python中想完成异步非阻塞 就需要先开启任务,然后执行其他操作,在某个地方等待task完成后返回 并退出
        print('我会不会先出现...')
        print('耗时:', time.time() - start_time)
        # nested()
        # print(await nested())
        # await task # 类似与线程的join方法,不同的时,这个放的位置决定着谁先执行,例如我们放到程序最后,将看到协程是最后才执行,await的意思可以看作是等待协程的结果。
        a = await task  # 等待的主要目的就是为了获取协程的结果
        print(a)
        # 注意这里的时间,和多线程类似的,当多线程没有join时,主线程会马上结束但是不会杀死子线程。这里也是一样,如果不等待协程的结果,主程序结束后不会杀死协程,协程将继续执行完毕
        print(time.strftime('%X'))
    
    asyncio.run(main())
    

    运行

    python demo.py
    

    预期的输出

    22:17:16
    我会不会先出现...
    耗时: 1.2159347534179688e-05
    我是异步内的任务,我已经完成了
    45
    22:17:18
    

    对比使用gevent协程实现异步任务

    import gevent
    from gevent import monkey; monkey.patch_all()
    import time
    
    
    def nested():
        time.sleep(2)
        print('我是异步内的任务,我已经完成了')
        return 45
    
    def main():
        start_time = time.time()
        print('我会不会先出现...')
        gevent.spawn(nested)
        time.sleep(3) # 这里停顿3秒的目的就是让主进程在三秒后结束,然后看协程是否被异步执行
        print('耗时:', time.time() - start_time)
    
    if __name__ == '__main__':
        main()
    

    得到的输出:

    我会不会先出现...
    我是异步内的任务,我已经完成了
    耗时: 3.0009806156158447
    

    再来修改使用asyncio的例子:

    import asyncio
    import time
    
    # Python 协程属于可等待对象,因此可以在其他协程中被等待 Python异步非阻塞雏形
    async def nested():
        time.sleep(2)
        # await asyncio.sleep(2)
        print('我是异步内的任务,我已经完成了')
        return 45
    
    async def main():
        print(time.strftime('%X'))
        start_time = time.time()
        task = asyncio.create_task(nested())  # 使用task去执行协程,就可以达到异步的效果,我们任务在这里是已经开启了协程,只是结果在其他位置等待。因此这个代码预期就是异步的。
        # await nested() # 这种调用会等待协程完成之后在继续向下执行,也就是协程会阻塞在这里,常用于同步协程
        # await task # 它会等待任务完成返回后 往下执行,如果在Python中想完成异步非阻塞 就需要先开启任务,然后执行其他操作,在某个地方等待task完成后返回 并退出
        print('我会不会先出现...')
        print('耗时:', time.time() - start_time)
        # nested()
        # print(await nested())
        # await task # 类似与线程的join方法,不同的时,这个放的位置决定着谁先执行,例如我们放到程序最后,将看到协程是最后才执行,await的意思可以看作是等待协程的结果。
        # a = await task  # 等待的主要目的就是为了获取协程的结果
        # print(a)
        # 注意这里的时间,和多线程类似的,当多线程没有join时,主线程会马上结束但是不会杀死子线程。这里也是一样,如果不等待协程的结果,主程序结束后不会杀死协程,协程将继续执行完毕
        print(time.strftime('%X'))
    
    asyncio.run(main())
    time.sleep(3)
    

    得到的输出:

    22:30:23
    我会不会先出现...
    耗时: 1.049041748046875e-05
    22:30:23
    我是异步内的任务,我已经完成了
    

    发现当使用time.sleep后任务也会被异步的执行,只是不在等待结果,此时不关心异步任务的执行结果

    对比nodejs中的异步非阻塞代码

    // demo.js
    function timeout(ms) {
        setTimeout(function(){
            console.log('输出...')
            var end_time = (new Date().getTime()) / 1000
            console.log('程序真正完成时间:', end_time - start_time)
        },ms);
        
    }
    // nodejs 就是一个完全的非阻塞的
    var start_time = (new Date().getTime()) / 1000
    timeout(2000)
    var end_time = (new Date().getTime()) / 1000
    console.log('完成时间:', end_time - start_time)
    

    运行

    node demo.js
    

    预期的输出

    完成时间: 0.0009999275207519531
    输出...
    程序真正完成时间: 2.003000020980835
    
    展开全文
  • 让你指定循环你的例子:await f1await asyncio.wait_for(f1, None) # or simply asyncio.wait_for(f1)两个等待都将无限期地等待结果(或异常).在这种情况下,平原等待更合适.另一方面,如果您提供超时参数,它将等待具有...

    wait_for提供了两个更多功能:

    >允许定义超时,

    >让你指定循环

    你的例子:

    await f1

    await asyncio.wait_for(f1, None) # or simply asyncio.wait_for(f1)

    两个等待都将无限期地等待结果(或异常).在这种情况下,平原等待更合适.

    另一方面,如果您提供超时参数,它将等待具有时间约束的结果.如果超过超时时间,则会引发TimeoutError,将来会被取消.

    async def my_func():

    await asyncio.sleep(10)

    return 'OK'

    # will wait 10s

    await my_func()

    # will wait only 5 seconds and then will raise TimeoutError

    await asyncio.wait_for(my_func(), 5)

    另一件事是循环参数.在大多数情况下你不应该被打扰,用例是有限的:为测试注入不同的循环,运行其他循环…

    这个参数的问题是,所有后续任务/函数也应该传递循环…

    展开全文
  • 1.asyncio.wait asyncio.gather这两个都是接受多个future或coro组成的列表,但是不同的是,asyncio.gather会将列表中不是task的coro预先封装为future,而wait则不会。 不过,loop.run_until_complete(asyncio.wait...
  • 本文整理匯總了Python中asyncio.ensure_future方法的典型用法代碼示例。如果您正苦於以下問題:Python asyncio.ensure_future方法的具體用法?Python asyncio.ensure_future怎麽用?Python asyncio.ensure_future...
  • 本文整理汇总了Python中asyncio._get_running_loop方法的典型用法代码示例。如果您正苦于以下问题:Python asyncio._get_running_loop方法的具体用法?Python asyncio._get_running_loop怎么用?Python asyncio._get...
  • I'm reading 'Fluent Python' by 'Luciano Ramalho' over and over, but I couldn't understand asyncio.sleep's behavior inside asyncio.Book says at one part:Never use time.sleep in asyncio coroutines unles...
  • threading.Eventdef run(self):while not self.stop_event.wait(3): # i.e. repeat every 3 secpass # do stuff这个想法是其中一些是在他们自己的线程中运行的,并且在某个时刻,一个线程执行stop_event.set(),这自.....
  • asyncio 系列四、期程 — asyncio.Future

    千次阅读 2019-05-24 16:09:03
    asyncio的期程 官网链接:https://docs.python.org/zh-cn/3/library/asyncio-future.html#asyncio.Future 其实期程指的是,classasyncio.Future返回的实例,官网翻译为期程。 一、期程函数 asyncio....
  • Python3.7的新API:asyncio.run()Python3.7的正式版本已经发布有一段时间了,出了内置的breakpoint()断点函数,颇受争议的dataclass,自定义模块里的__getattr__()和__dir__()魔法方法等新特性外以及一些底层的改进外...
  • 参考教程实例代码这是一段取自于官方文档的代码,对于这个asyncio.sleep(1)有点不理解,官方文档对于它的描述是"This function is a coroutine."对于yield from它的用法又是这样解释的:result = await coroutine or ...
  • 参考教程官方文档和廖雪峰教程实例代码这是一段取自于官方文档的代码,对于这个asyncio.sleep(1)有点不理解,官方文档对于它的描述是”This function is a coroutine.”对于yield from它的用法又是这样解释的:result...
  • Python之asyncio.Queue

    千次阅读 2019-02-07 22:43:53
    asyncio.Queue一个队列,规则是先进先出,先存入先取出。 官方文档上有个例子: https://asyncio.readthedocs.io/en/latest/producer_consumer.html 代码如下: import asyncio import random async def ...
  • python asyncio asyncio wait

    2019-07-20 10:32:00
    import asyncio import time async def get_html(url): print("start get url") await asyncio.sleep(2) # 不能使用time.sleep(),这样的话是同步,就不是异步;await就相当于yield from print("end get url...
  • python asynciowait 和 gather

    千次阅读 2019-11-28 15:42:00
    wait 和 gather 两者都是在协程需要并发的时候使用。 wait接受一个协程列表,返回done, peding两个集合,done里面是完成任务的协程,pending表示仍在跑的协程,通过协程.result()的方法来获取完成的结果。<...
  • python里使用队列asyncio.Queue进行通讯

    千次阅读 2017-09-09 18:34:39
    asyncio.Queue与其它队列是一样的,都是先进先出,它是为协程定义的,例子如下:import asyncio async def consumer(n, q): print('consumer {}: starting'.format(n)) while True: print('consumer {}: ...
  • 使用asyncio.run_coroutine_threadsafe动态添加协程任务到事件循环中一. 官方文档根据asyncio的文档介绍,asyncio的事件循环不是线程安全的,一个event loop只能在一个线程内调度和执行任务,并且同一时间只有一个...
  • 本文整理汇总了Python中asyncio.isfuture方法的典型用法代码示例。如果您正苦于以下问题:Python asyncio.isfuture方法的具体用法?Python asyncio.isfuture怎么用?Python asyncio.isfuture使用的例子?那么恭喜您,...
  • 事件对象asyncio.Event是基于threading.Event来实现的。事件可以一个信号触发多个协程同步工作,例子如下:import asyncio import functools def set_event(event): print('setting event in callback') event....
  • 什么我正在使用asyncio开发一个监视进程,它在各个地方的任务等待各种持续时间的asyncio.sleep调用.有一些时间点,我希望能够中断所有说的asyncio.sleep调用并让所有任务正常进行,但我找不到如何做到这一点.一个示例是...
  • The communicate() and wait() methods don’t take a timeout parameter: use the wait_for() function使用wait_for()对communicate()施加超时很容易,但是我找不到从中断的communicate()调用中检索部分结果的方法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,501
精华内容 2,600
关键字:

asyncio.wait