zoukankan      html  css  js  c++  java
  • Python-asyncio异步编程-事件驱动编程

    基本介绍

     # Event source  / Event loop /Event handler   await
     Event Loop  callbacks 
     awaitable对象: Coroutines  Tasks  Futures
     语法: async/await 
     相关概念 阻塞Blocking    IO-bound
    
     #The event loop is the core of every asyncio application. 
        Event loops run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses.
     # 协程  任务 future 回调函数
     # 状态  挂起 执行  阻塞
     # 协程函数: 定义形式为 async def 的函数
    
    
    API
       Low-level API  低层级 API 以支持 库和框架的开发
          Event Loop Methods: loop.run_until_complete  loop.call_soon
       High-level API 
        create_task()     Start an asyncio Task.
    	run()           Create event loop, run a coroutine, close the loop.
    	await gather()  Schedule and wait for things concurrently.
    	await wait()    Monitor for completion.
      # asyncio.ensure_future(coroutine) 和 loop.create_task(coroutine)都可以创建一个task
     #CPU- (计算密集型) 和 I/O bound(I/O密集型)
    

    代码示例

    #!/usr/bin/env python3
    
    import time
    import asyncio
    
    # awaitable objects: coroutines, Tasks, and Futures.
    async def do_some_work(x):
        print('Waiting: ', x)
    
    
    def callback(future):
        print('Callback: ', future.result())
    
    
    if __name__ == "__main__":
        now = lambda : time.time()
        start = now()
        coroutine_01 = do_some_work(2)
        loop = asyncio.get_event_loop()
        loop.run_until_complete(coroutine_01)
    
        print('TIME01 : ', now() - start)
    
        # asyncio.ensure_future(coroutine) 和 loop.create_task(coroutine)都可以创建一个task
        coroutine1 = do_some_work(3)
        loop = asyncio.get_event_loop()
        # task = asyncio.ensure_future(coroutine)
        task = loop.create_task(coroutine1)
        print("M1: ", task)
        loop.run_until_complete(task)
        print("M2: ", task)
        print('TIME: ', now() - start)
        # task是Future的子类
        print(isinstance(task, asyncio.Future))
    
        coroutine2 = do_some_work(4)
        loop = asyncio.get_event_loop()
        task = asyncio.ensure_future(coroutine2)
        task.add_done_callback(callback)
        loop.run_until_complete(task)
    
        print('TIME: ', now() - start)
        # 协程遇到await,事件循环将会挂起该协程,执行别的协程,直到其他的协程也挂起或者执行完毕,再进行下一个协程的执行
        # 一群task任务
        # asyncio.wait(tasks) 也可以使用 asyncio.gather(*tasks) ,前者接受一个task列表,后者接收一堆task
        # syncio.gather创建协程对象,那么await的返回值就是协程运行的结果。
        coroutine5 = do_some_work(5)
        coroutine6 = do_some_work(6)
        tasks = [
            asyncio.ensure_future(coroutine5),
            asyncio.ensure_future(coroutine6)
        ]  # 将协程作为参数创建任务
        loop = asyncio.get_event_loop()  # 创建事件循环
        loop.run_until_complete(asyncio.wait(tasks))  # 运行协程
        # 打印协程返回值,注意只有协程结束后才可获得返回值
        print("返回值:", tasks[0].result())
        print("返回值:", tasks[0].result())
    
    # Pending  Running  Done  Cancelled
    # 有一种方式实现这种类似master-worker的方案
    # 主线程用于监听队列,然后子线程的做事件循环的worker是一种方式。
    
    
    
    # To actually run a coroutine, asyncio provides three main mechanisms
    # 01.   asyncio.run() function
    # 02.  asyncio.create_task() function to run coroutines concurrently as asyncio Tasks.
    # Low low-level  
    
    #high
    #  asyncio.StreamReader  asyncio.StreamWrite  asyncio.open_connection  asyncio.open_unix_connection  asyncio.start_unix_server
    #  asyncio.create_subprocess_exec    asyncio.subprocess.PIPE  asyncio.create_subprocess_shell   asyncio.subprocess.STDOUT
    # asyncio.Queue  asyncio.PriorityQueue  asyncio.LifoQueue
    # asyncio.Lock  asyncio.Event  asyncio.Condition  asyncio.Semaphore  asyncio.BoundedSemaphore
    

    网络编程

    Concurrency is about dealing with lots of things at once.
    Parallelism is about doing lots of things at once.
    Not the same, but related.
    One is about structure, one is about execution.
    Concurrency provides a way to structure a solution to solve a problem that may (but not
    necessarily) be parallelizable.
       
                                                             ———— Rob Pike (Co-inventor of the Go language)	  
    	  
    网络编程里-阻塞IO、非阻塞IO、同步IO、异步IO等概念	
       进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态  
    
    事件驱动编程是一种网络编程范式
    I/O多路复用的本质就是用select/poll/epoll,去监听多个socket对象,
         如果其中的socket对象有变化,只要有变化,用户进程就知道了。
    select是不断轮询去监听的socket,socket个数有限制,一般为1024个;
      selectors
    poll还是采用轮询方式监听,只不过没有个数限制;
    epoll并不是采用轮询方式去监听了,而是当socket有变化时通过回调的方式主动告知用户进程	  
    
    功能与linux的epoll,还是select模块,poll等类似;实现高效的I/O multiplexing,  常用于非阻塞的socket的编程中
  • 相关阅读:
    集训笔记——dp继续
    集训笔记——各种dp(dp杂谈)
    集训笔记——dp
    洛谷P3197 [HNOI2008]越狱 题解
    集训笔记——杂题选讲(图论,dp)
    集训笔记——杂题选讲(带数学推导的递推、递归和dp,卡特兰数)
    滑动窗口+二分--P3957 跳房子
    差分+二分答案--P1083 借教室
    逆序对--P1966 火柴排队
    数位dp--P2657 [SCOI2009] windy 数
  • 原文地址:https://www.cnblogs.com/ytwang/p/15016245.html
Copyright © 2011-2022 走看看