zoukankan      html  css  js  c++  java
  • Python asyncio

    最近在看 ayncio 这块内容
    于是打算从 asyncio.run 这个 函数作为入口看下内部是如何工作的
    下面是源码以及一些分析

    如有问题, 欢迎交流

    另外 有没得大佬晓得 博客园的 markdown 怎么显示行号啊

    def run(main, *, debug=False):
    
        if events._get_running_loop() is not None:  # 获取当前是否含有 loop
            raise RuntimeError(
                "asyncio.run() cannot be called from a running event loop")
    
        if not coroutines.iscoroutine(main): #  判断是否是一个 coroutine
            raise ValueError("a coroutine was expected, got {!r}".format(main))
    
        loop = events.new_event_loop()  # 获取一个 loop
    
        """
        下面是获取一个 loop 的逻辑
        """
        # get_event_loop_policy().new_event_loop()
        # 其中 get_event_loop_policy 是获取 loop_policy
        # 在 linux 下 默认是使用 _UnixDefaultEventLoopPolicy # asyncio.unix_events._UnixDefaultEventLoopPolicy
        # loop 为 _UnixSelectorEventLoop 的一个实例 # asyncio.unix_events._UnixSelectorEventLoop
        """
        获取 loop end 
        """
    
        try:
            events.set_event_loop(loop)  # get_event_loop_policy().set_event_loop(loop)
            """
            get_event_loop_policy() -> _UnixDefaultEventLoopPolicy 一个实例
            set_event_loop()  # asyncio.events.BaseDefaultEventLoopPolicy#set_event_loop 
            给 loop_policy 设置 loop 
            放在 loop_policy 的 ThreadLocal 中 (引用变量)
            ps. 最近被引用变量坑的不行...有点怕(弱引用)
            """
    
            loop.set_debug(debug)
            """
            # todo 暂时不处理
            """
            return loop.run_until_complete(main)
            """
            asyncio.base_events.BaseEventLoop#run_until_complete
            """
            
            """以下是 run_until_complete 的逻辑"""
    
            def run_until_complete(self, future):
    
                self._check_closed() # 暂时不管
    
                new_task = not futures.isfuture(future) # 判断是否是 future toto  task???
                # todo asyncio.ensure_future asyncio.create_task 两者的差别
                future = tasks.ensure_future(future, loop=self)  # create task
                """
                asyncio.tasks.ensure_future
                看了下如果 future 是一个 coroutine 则会调用 create_task
                asyncio.base_events.BaseEventLoop#create_task
                # todo task 内容暂时不看
    
    
                future 是 _asyncio.Task 或者是 _asyncio.Future -----asyncio.futures.Future(划掉)
                Task 为 Future 的一个子类
                """
    
                if new_task:
                    # An exception is raised if the future didn't complete, so there
                    # is no need to log the "destroy pending task" message
                    future._log_destroy_pending = False
    
                future.add_done_callback(_run_until_complete_cb)
                """
                add_done_callback 是写在 so 文件中了 我并不知道他干了点啥 ~~~~(>_<)~~~~
    
    
                可能类似这个吧:
                def add_done_callback(self, fn, *, context=None):
                    '''Add a callback to be run when the future becomes done.
    
                    The callback is called with a single argument - the future object. If
                    the future is already done when this is called, the callback is
                    scheduled with call_soon.
                    '''
                    if self._state != _PENDING:
                        self._loop.call_soon(fn, self, context=context)
                    else:
                        if context is None:
                            context = contextvars.copy_context()
                """
    
                # todo 有时间再看
                try:
                    self.run_forever()
                except:
                    if new_task and future.done() and not future.cancelled():
                        # The coroutine raised a BaseException. Consume the exception
                        # to not log a warning, the caller doesn't have access to the
                        # local task.
                        future.exception()
                    raise
                finally:
                    future.remove_done_callback(_run_until_complete_cb)
                if not future.done():
                    raise RuntimeError('Event loop stopped before Future completed.')
    
                return future.result()
            """-------- run_until_complete ---------   end"""
    
        finally:
            try:
                _cancel_all_tasks(loop)
                loop.run_until_complete(loop.shutdown_asyncgens())
            finally:
                events.set_event_loop(None)
                loop.close()
    
    
    
  • 相关阅读:
    Bash
    FireDAC
    忽然看到字符汉字特殊字符在计算机中的存储方式
    Windows环境下使用Nginx搭建负载均衡
    Session跨域、Session共享、Mode=StateSever方式解决问题
    原生Js在各大浏览器上、火狐、ie、谷歌、360等出现的不兼容问题。
    Sina 新浪Ip归属地Api 很好用的,使用get请求
    前端页面使用 Json对象与Json字符串之间的互相转换
    使用bootstrap 弹出效果演示
    Mvc自定义路由让支持.html的格式
  • 原文地址:https://www.cnblogs.com/twotigers/p/10629574.html
Copyright © 2011-2022 走看看